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

时间:2023-03-08 20:48:21

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

阶段:当前合并了的区间长度

状态:区间的左右端点

状态转移方程:\(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;
}