51nod 1021 石子归并 -动态规划
2017-12-06 17:20
253 查看
题目链接:1021
贪心似乎无法求解。
dp[i][j]代表归并[j,j+i-1]这段区间的花费,归并每次是归并两堆石子,则划分这段区间有i-1种方式,所以dp[i][j]=max(dp[k][j]+dp[i-k][j+k]+sum[i][j]),k∈[1,i-1],其中sum[i][j]是这段区间石子数量和。
然后就是自底向上dp了.
代码:
贪心似乎无法求解。
dp[i][j]代表归并[j,j+i-1]这段区间的花费,归并每次是归并两堆石子,则划分这段区间有i-1种方式,所以dp[i][j]=max(dp[k][j]+dp[i-k][j+k]+sum[i][j]),k∈[1,i-1],其中sum[i][j]是这段区间石子数量和。
然后就是自底向上dp了.
代码:
#include<iostream> #include<cstring> #include<climits> using namespace std; long long dp[110][110]; long long sum[110][110]; int main(){ long long ans=0; int n; cin>>n; for(int i=1;i<=n;i++)for(int j=0;j<n;j++)dp[i][j]=INT_MAX; for(int i=0;i<n;i++)cin>>sum[1][i]; //先单独地把个个区间石子数量和单独计算出来 for(int i=2;i<=n;i++){ sum[i][0]=0; for(int j=0;j<i;j++)sum[i][0]+=sum[1][j]; } for(int i=2;i<=n;i++){ for(int j=1;j+i<=n;j++){ sum[i][j]=sum[i][j-1]-sum[1][j-1]+sum[1][j+i-1]; } } memset(dp[1],0,sizeof(dp[1])); for(int i=2;i<=n;i++){ for(int j=0;j+i<=n;j++){ for(int k=1;k<i;k++)if(dp[i][j]>dp[k][j]+dp[i-k][j+k]+sum[i][j])dp[i][j]=dp[k][j]+dp[i-k][j+k]+sum[i][j]; } } cout<<dp [0]; }
相关文章推荐
- 51nod 1021 石子归并(动态规划)
- 51nod 1021 石子归并 (动态规划 简单代码)
- 51NOD 1021 石子归并
- 51Nod 1021 石子归并v1
- 51Nod - 1021石子归并(区间DP)
- 51nod 1021 石子归并(区间dp 详细解释)
- 1021 石子归并-51Nod
- 【51nod】1021 石子归并
- 51Nod 1021 石子归并
- 51Nod - 1021 石子归并(经典dp)
- 51Nod 1021 石子归并
- 51nod 1021 石子归并(dp-矩阵连乘)
- 51nod 1021 石子归并
- 51nod 1021 石子归并
- 51nod 1021 石子归并 dp
- 经典问题二.【区间dp】石子归并 51nod 1021
- 51nod 1021 石子归并
- 51Nod-1021-石子归并
- 51nod 1021 石子归并(基础dp)
- AC日记——石子归并 51nod 1021