区间dp——合并金币

链接:https://www.nowcoder.com/questionTerminal/6d3ccbc5b6ad4f12b8fe4c97eaf969e0
来源:牛客网

 有 N 堆金币排成一排,第 i 堆中有 C[i] 块金币。每次合并都会将相邻的两堆金币合并为一堆,成本为这两堆金币块数之和。经过N-1次合并,最终将所有金币合并为一堆。请找出将金币合并为一堆的最低成本。

其中,1 <= N <= 30,1 <= C[i] <= 100

输入描述:

第一行输入一个数字 N 表示有 N 堆金币

第二行输入 N 个数字表示每堆金币的数量 C[i]

输出描述:

输出一个数字 S 表示最小的合并成一堆的成本

示例1

输入

4
3 2 4 1

输出

20

示例2

输入

30
10 20 30 40 50 60 70 80 90 100 99 89 79 69 59 49 39 29 19 9 2 12 22 32 42 52 62 72 82 92

输出

7307

遇到相邻的,就要往区间dp上想

注意初始化。

代码:

#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
int main()
{
    int n;
    int c[50],sum[50],dp[50][50];
    while(scanf("%d",&n)!=EOF){
    memset(dp,INF,sizeof(dp));
    memset(sum,0,sizeof(sum));
    for(int i=1;i<=n;i++){
        scanf("%d",&c[i]);
        sum[i]=sum[i-1]+c[i];
        dp[i][i]=0;
    }
    for(int len=1;len<=n;len++){///区间长度
        for(int i=1;i+len<=n;i++){///首
            int wei=i+len;
            for(int k=i;k<wei;k++)///中间。尾是“j+i-1”
            {
                dp[i][wei]=min(dp[i][wei],dp[i][k]+dp[k+1][wei]+sum[wei]-sum[i-1]);
            }
        }
    }
       printf("%d\n",dp[1][n]);
    }
}
发布了565 篇原创文章 · 获赞 110 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/xianpingping/article/details/104849192