石子合并(一排)——动态规划,前缀和

石子合并

https://ac.nowcoder.com/acm/problem/51170

题目描述

链接:https://ac.nowcoder.com/acm/problem/51170
来源:牛客网
图片说明

题目思路

原问题:找到n堆石子合并的最小代价dp[1][n]
子问题:找到第i到j堆石子合并的最小代价dp[i][j]
第i到j堆石子合并的最小代价=第i到k堆石子合并的最小代价+第(k+1)到j堆石子合并的最小代价+第i到j堆石子数量和.
即一次合并的最小代价,不仅是其划分出的的这两堆石子在自身合并时带来的代价和,还要考虑这两堆石子自身的数量和。
设sun[i]代表从第1堆到第i堆石子数量之和,则有
dp[i][j] = min(dp[i][j], dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1])

完整代码

#include <bits/stdc++.h>
using namespace std;
int a[310];
long long dp[310][310], sum[310];

int main()
{
    long long res = 0;
    int n;
    scanf("%d",&n);
    int i=1;
    while(i<=n)
    {
        scanf("%d",&a[i]);
        i++;
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=i;j++)
        {
            sum[i]+=a[j];
        }    
    }

    for(int i=n-1;i>0;i--)
    {
        for(int j=i+1;j<=n;j++)
        {
            for(int k=i;k<j;k++)
            {
                if(dp[i][j] == 0)
                    dp[i][j] = dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1];
                else
                    dp[i][j] = min(dp[i][j],dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1]);
            }
        }
    }
    printf("%d",dp[1][n]);
    return 0;
}
全部评论

相关推荐

如题,他是要劝退我了吗
椛鸣:根据你的时间 来给你安排任务 如果你时间长 可能会参与到一些长期的项目 时间短 那就只能做点零工
点赞 评论 收藏
分享
没有offer的呆呆:薪资有的时候也能说明一些问题,太少了活不活得下去是一方面,感觉学习也有限
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务