和谐宿舍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;
}

 

posted @ 2020-06-06 20:41  西伯利亚挖土豆  阅读(197)  评论(0编辑  收藏  举报