和谐宿舍2
#include <bits/stdc++.h> using namespace std; const int maxn=100+10; //开新木板不一定要刚好一样大,可以比i大 //不开的情况不考虑,因为开了的情况因为开的大小由最大值确定,所以包含了不开的情况 //他给的测试数据有迷惑性 //这个题根据经验想到了要枚举,在根据数据发现可以多开 => 枚举最后一个木板包含的数目,并用最大值开那个木板 //可以多枚举,反正取最大值,只要合法,比如不确定某个值,那就合法枚举然后max,因为无法确定i-1的最优情况的 int n,dp[maxn][maxn],a[maxn],k,s[maxn][maxn]; int main() { cin>>n>>k; memset(dp,0x3f, sizeof(dp)); for(int i=1;i<=n;i++) cin>>a[i]; //获得区间内的最大值 for(int i=1;i<=n;i++){ int m=0; for(int j=i;j<=n;j++){ m=max(m,a[j]); s[i][j]=m; } } //初始化一个木板的情况,因为一个木板的情况要开 for(int i=0;i<=n;i++) dp[i][0]=dp[0][i]=0; for(int i=1;i<=n;i++) dp[i][1]=s[1][i]*i; for(int i=2;i<=n;i++){ for(int j=2;j<=k;j++){ for(int p=1;p<i;p++){ dp[i][j]=min(dp[i][j],dp[p][j-1]+s[p+1][i]*(i-p)); } } } cout<<dp[n][k]<<endl; return 0; }