合并石子 (区间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 }

 

转载于:https://www.cnblogs.com/Willendless/p/9381639.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值