资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
我的某室友学过素描,墙上有n张他的作品。这些作品都是宽度为1,高度不定的矩形,从左到右排成一排,且底边在同一水平线上。
宿舍评比就要来了,为了及格,我们决定买不多于m块的矩形木板,把这些作品和谐掉。要求木板也从左到右排成一排,且底边与作品的底边在同一水平线上。
在能够把所有作品和谐掉的前提下,我们希望这些木板的面积和最小,问最小面积和。
输入格式
第一行两个数n和m,表示作品数和木板数;
第二行n个数Hi,表示从左到右第i个作品的高度。
输出格式
一行一个数ans,表示答案。
样例输入
5 2
4 2 3 5 4
样例输出
22
数据规模和约定
对于30%的数据:1<=n,m<=10;
对于100%的数据:1<=n,m<=100,1<=Hi<=10000。
代码
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
int *a;
int n_,m_;
int s[1000001][101]={0};
int dfs(int n,int m){
if(s[n][m]!=0) return s[n][m];//如果前面计算过就不用再计算了
if(m==1){ //剩下的部分只能用一块板子
int t=-1;
for(int i=0;i<n;i++){
t=max(t,a[i]);
}
s[n][m]=n*t;
return n*t;
}
if(n==1){ //只剩一块涂鸦,而且板子还有剩余
s[n][m]=a[n-1];
return a[n-1];
}
if(n==0) return 0;
int t=1000000000;
for(int i=1;i<=n;i++){//将连续的i块涂鸦用同一块板子遮盖
int tmp=-1;
for(int j=n;j>n-i;j--){//计算连续i块涂鸦中高度最高的
tmp=max(tmp,a[j-1]);
}
t=min(dfs(n-i,m-1)+i*tmp,t);//将各种情况中,遮盖面积最小的值保存下来
}
s[n][m]=t;
return t;
}
int main(){
cin>>n_>>m_;
a=new int[n_];
for(int i=0;i<n_;i++){
cin>>a[i];
}
cout<<dfs(n_,m_);
return 0;
}