【codevs1048】石子归并(初级版)

采用动态规划的原因:合并有一定次序,即:只能相邻石子进行合并。

阶段:当前合并了的区间长度
状态:区间的左右端点
状态转移方程:\(dp[l][r]=min\{dp[l][r],dp[l][k]+dp[k+1][r]\},k\in[l,r)\)

代码如下

#include <bits/stdc++.h>
using namespace std;
const int maxn=310;

int n,sum[maxn],dp[maxn][maxn];

void read_and_parse(){
    scanf("%d",&n);
    memset(dp,0x3f,sizeof(dp));
    for(int i=1;i<=n;i++){
        scanf("%d",&sum[i]);
        sum[i]+=sum[i-1];
        dp[i][i]=0;
    }
}

void solve(){
    for(int len=2;len<=n;len++)
        for(int l=1;l<=n-len+1;l++){
            int r=l+len-1;
            for(int k=l;k<r;k++)
                dp[l][r]=min(dp[l][r],dp[l][k]+dp[k+1][r]);
            dp[l][r]+=sum[r]-sum[l-1];
        }
    printf("%d\n",dp[1][n]);
}

int main(){
    read_and_parse();
    solve();
    return 0;
}
posted @ 2018-10-19 14:10  shellpicker  阅读(128)  评论(0编辑  收藏  举报