【石子合并】_DP

石子合并

    在一个直线操场的四周摆放着n堆石子。现要将石子有次序地合并成一堆。规定每次只能选相邻的2 堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分。

   试设计一个算法,计算出将n堆石子合并成一堆的最小得分和最大得分。

 

【输入文件】

包含两行,第1 行是正整数n(1<=n<=100),表示有n堆石子。

第2行有n个数,分别表示每堆石子的个数。

 

【输出文件】

输出两行。

第1 行中的数是最小得分;第2行中的数是最大得分。

 

【输入样例】

4

44 5 9

 

【输出样例】

43

54

 

#include 
   
   
    
    
#include 
    
    
     
     
#define max 9999

int a[101];
int dp_min[101][101];
int dp_max[101][101];
int sum[101][101];

int main()
{
       int n;
       scanf("%d",&n);

       int i;
       int j,k;
       for(i=1;i<=n;i++)
       {
              scanf("%d",&a[i]);
       }

       memset(sum,0,sizeof(sum));

       for(i=1;i<=n;i++)
       {
              for(j=1;j<=n;j++)
              {
                     if(i<=j)
                     {
                            for(k=i;k<=j;k++)
                            {
                                   sum[i][j]+=a[k];
                            }
                     }
                     else
                     {
                            for(k=j;k<=i;k++)
                            {
                                   sum[i][j]+=a[k];
                            }
                     }          
              }
       }
       memset(dp_max,0,sizeof(dp_max));

       for(i=1;i<=n;i++)
       {
              for(j=1;j<=n;j++)
              {
                     dp_min[i][j]=max;
              }
       }

       for(j=1;j<=n;j++)
       {
              dp_min[j][j]=0;
       }
       int len;
       for(len=1;len<=n;len++)
              for(i=1;i<=n-len+1;i++)
              {
                     j=i+len-1;

                     for(k=i;k
     
     
      
      dp_min[i][k]+dp_min[k+1][j]+sum[i][j])
                            {
                                   dp_min[i][j]=dp_min[i][k]+dp_min[k+1][j]+sum[i][j];
                            }
                            if(dp_max[i][j]
      
      
     
     
    
    
   
   

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值