1051: 石子合并1

看到这个博客点击打开链接http://www.cnblogs.com/SCAU_que/articles/1893979.html

才看懂的,用博主的代码完全可以A掉这题,真心感谢博主,啦啦啦

另附上本题代码

#include<cstdio>
  #define N 205
  /*
  *求合并过程中
  *最少合并堆数目
  **/
  int MatrixChain_min(int p[N],int n)
 {
         //定义二维数组m[i][j]来记录i到j的合并过成中最少石子数目
         //此处赋值为-1
  
         int m[N][N];
       for(int x=1;x<=n;x++)
         for(int z=1;z<=n;z++)
         {
             m[x][z]=-1;           
         }
 
      int min=0;
 
                                                           //当一个单独合并时,m[i][i]设为0,表示没有石子
      for(int g = 1;g<=n;g++) m[g][g]=0;
 
                                                           //当相邻的两堆石子合并时,此时的m很容易可以看出是两者之和
      for(int i=1;i<=n-1;i++)
     {
         int j=i+1;
         m[i][j]=p[i]+p[j];
     }
 
                                                           //当相邻的3堆以及到最后的n堆时,执行以下循环
     for(int r=3; r<=n;r++)
          for(int i=1;i<=n-r+1;i++)
          {
              int j = i+r-1;                               //j总是距离i   r-1的距离
              int sum=0;
                                                           //当i到j堆石子合并时最后里面的石子数求和得sum
              for(int b=i;b<=j;b++)
                  sum+=p[b];
 
              // 此时m[i][j]为i~j堆石子间以m[i][i]+m[i+1][j]+sum结果,这是其中一种可能,不一定是最优
              //要与下面的情况相比较,唉,太详细了
 
              m[i][j] = m[i+1][j]+sum;
 
              //除上面一种组合情况外的其他组合情况
              for(int k=i+1;k<j;k++)
              {
                  int t=m[i][k]+m[k+1][j]+sum;
                  if(t<m[i][j])
                      m[i][j] = t;
 
              }
          }
           //最终得到最优解
          min=m[1][n];
          return min;
 
         
 }
 

 int main()
 {
       int stone[N];
       int min=0;
       int n;
       scanf("%d",&n);
       for(int i=1;i<=n;i++)
           scanf("%d",&stone[i]);
 
       min= MatrixChain_min(stone,n);

     printf("%d\n",min);
 
     return 0;
 
 }


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值