SSL_2863【合并石子】

   日期:2020-08-22     浏览:91    评论:0    
核心提示:合并石子题目在一个操场上一排地摆放着N堆石子。现要将石子有次序地合并成一堆。规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分。请设计一个程序,计算出将N堆石子合并成一堆的最小得分。输入每组数据第1行为一个正整数N(2<=N<=100),以下N行,每行一个正整数,小于10000,分别表示第i堆石子的个数(1<=i<=N)。输出对于每组数据输出一个正整数,即最小得分Sample Input713781621418Sample

合并石子

题目

在一个操场上一排地摆放着N堆石子。现要将石子有次序地合并成一堆。规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分。请设计一个程序,计算出将N堆石子合并成一堆的最小得分。

输入

每组数据第1行为一个正整数N(2<=N<=100),以下N行,每行一个正整数,小于10000,分别表示第i堆石子的个数(1<=i<=N)。

输出

对于每组数据输出一个正整数,即最小得分

Sample Input

7
13
7
8
16
21
4
18

Sample Output

239

解析

这道题就是一行数,每次将两个石子合并并得到新石子的得分
贪心不能用,整体最优解并不代表部分最优解
所以,我们使用DP,动态规划常用从部分整体最优解的拆分来得到最优解法的递归式,我们可以想到,此处是由2堆石子合并,所以最终最优解肯定是由两个局部最优解加上整体的和求得。
上代码!

代码1

#include<iostream>
#include<cstdio>
using namespace std;
long long n,a[101],b[101][101],s[101];
int main()
{
    cin>>n;
    for(long long i=1;i<=n;i++)cin>>a[i];
    for(long long i=1;i<=n;i++)s[i]=s[i-1]+a[i];
    for(long long i=n-1;i>=1;i--)//枚举边界
 {
  for(long long j=i+1;j<=n;j++)//枚举长度
  {
            b[i][j]=0x7f7f7f7f;
   for(long long k=i;k<=j-1;k++)b[i][j]=min(b[i][j],b[i][k]+b[k+1][j]+s[j]-s[i-1]);
  }
 }
    cout<<b[1][n];
    return 0;
}

代码2

#include<iostream>
#include<cstdio>
using namespace std;
long long n,a[101],b[101][101],c[101];
int main()
{
    cin>>n;
    for(long long i=1;i<=n;i++)cin>>a[i];
    for(long long i=1;i<=n;i++)c[i]=c[i-1]+a[i];
    for(long long i=2;i<=n;i++)//枚举长度
 {
  for(long long j=1;j<=n-i+1;j++)//枚举边界
  {
   long long t=j+i-1;
            b[j][t]=0x7f7f7f7f;
   for(long long k=j;k<=t;k++)b[j][t]=min(b[j][t],b[j][k]+b[k+1][t]+c[t]-c[j-1]);
  }
 }
    cout<<b[1][n];
    return 0;
}

代码3

#include<iostream>
#include<cstdio>
using namespace std;
int n,a[101],b[101][101],s[101];//b[i][j]表示从第i个起,接下来j个数合并的最小代价
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int i=1;i<=n;i++)s[i]=s[i-1]+a[i];
    for(int l=1;l<=n;l++)//枚举边界
 {
  for(int i=1;i<=n;i++)//枚举长度
  {
   b[i][l]=0x7f7f7f7f;
   for(int j=1;j<l;j++)b[i][l]=min(b[i][l],b[i+j][l-j]+b[i][j]+s[l+i-1]-s[i-1]);
   if(l==1)b[i][l]=0;
  }
 }
    cout<<b[1][n];
    return 0;
}
 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服