您的位置:首页 > 其它

51Nod - 1021石子归并(区间DP)

2018-03-07 21:25 483 查看

题意分析

区间dp

状态设计

dp[i][j]表示从第i堆石子到第j堆石子的最小花费。

状态转移

dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]+sum[i][j])dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]+sum[i][j])。

其中sum[i][j]=∑jk=ia[k]sum[i][j]=∑k=ija[k]。即第i堆到第j堆石子求和。

详情请见代码

代码总览

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int nmax = 105;
const int INF = 0x3f3f3f3f;
int a[nmax];
int sum[nmax][nmax];
int dp[nmax][nmax];
int n;
int main(){
while(scanf("%d",&n)!=EOF){
memset(a,0,sizeof a);
memset(sum,0,sizeof sum);
memset(dp,0,sizeof dp);
for(int i = 1 ;i<=n;++i) {
scanf("%d",&a[i]);
sum[i][i] = a[i];
}
for(int i = 1;i<=n;++i)
for(int j=i+1;j<=n;++j)
sum[i][j] = sum[i][j-1] + a[j];
for(int len = 2;len<=n;++len){
for(int i = 1;i<=n-len+1;++i){
int j = i+len-1;
dp[i][j] = INF;
for(int k = i;k<=j-1;++k){
dp[i][j] = min(dp[i][j],dp[i][k]+dp[k+1][j] + sum[i][j]);
}
}
}

printf("%d\n",dp[1]
);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  区间dp