合并石子 (区间dp+前缀和)
Posted willendless
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了合并石子 (区间dp+前缀和)相关的知识,希望对你有一定的参考价值。
【题目描述】
N堆石子。现要将石子有次序地合并成一堆。规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分。计算出将N堆石子合并成一堆的最小得分。
【题目链接】
http://ybt.ssoier.cn:8088/problem_show.php?pid=1274
【算法】
若每一步决策采用贪心,则所作出的决策具有后效性,故采用动态规划。考虑决策序列,dp【i】【j】表示合并i到j堆石子最少得分,状态转移方程是dp【i】【j】=min(dp【i】【k】+dp【k+1】【j】)+a【j】-a【i-1】(a【j】表示前j堆的石子数之和)其中k从i到j-1。决策顺序是按区间长度由小到大。
【代码】
1 #include <bits/stdc++.h> 2 using namespace std; 3 int n,i,j,k; 4 int a[110],dp[110][110]; 5 int main() 6 { 7 scanf("%d",&n); 8 memset(dp,0x3f,sizeof(dp)); 9 for(i=1;i<=n;i++) scanf("%d",&a[i]),dp[i][i]=0,a[i]+=a[i-1]; 10 for(i=1;i<n;i++) 11 for(j=1;j+i<=n;j++) 12 for(k=0;k<i;k++) 13 dp[j][j+i]=min(dp[j][j+i],dp[j][j+k]+dp[j+k+1][j+i]+a[j+i]-a[j-1]); 14 printf("%d",dp[1][n]); 15 return 0; 16 }
以上是关于合并石子 (区间dp+前缀和)的主要内容,如果未能解决你的问题,请参考以下文章