【入门dp】--石子归并

1048 石子归并

 

时间限制: 1 s
空间限制: 128000 KB
题目等级 : 黄金 Gold
 
题目描述 Description

有n堆石子排成一列,每堆石子有一个重量w[i], 每次合并可以合并相邻的两堆石子,一次合并的代价为两堆石子的重量和w[i]+w[i+1]。

问安排怎样的合并顺序,能够使得总合并代价达到最小。

输入描述 Input Description

第一行一个整数n(n<=100)

第二行n个整数w1,w2...wn  (wi <= 100)

输出描述 Output Description

一个整数表示最小合并代价

样例输入 Sample Input

4

4 1 1 4

样例输出 Sample Output

18

解:dp【i】【j】存的是i~j這段距离的最优解;如何求出的呢

       先求相邻两个的最优解(就一个解),然后通过2个的解

       依次循环比较,得出3个最优解,以此类推,最后求出n,

       然后根据dp【】【】存的内容进行解题,这题就是输出

       dp【1】【n】,求出n堆石子的最优解,1到n

#include <stdio.h>
int dp[101][101],sum[101]={0},s[101];
int main()
{
    int n,i,j,t,k,mins,len;
    scanf("%d",&n);
    for(i=1;i<=n;i++)
    {
        scanf("%d",&s[i]);
        sum[i]=s[i]+sum[i-1];
    }
    for(len=2;len<=n;len++)//在计算所有三~n个在一起的
    {
        for(i=1;i<=n-len+1;i++)//先计算所有两个在一起的
        {
            j=i+len-1;
            mins=9999999;
            for(k=i;k<j;k++)//从2-n依次解决
            {
                t=dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1];//计算这一段的值,通过下面找出最小值
                if(mins>t)
                    mins=t;
            }
            dp[i][j]=mins;
        }
    }
    printf("%d
",dp[1][n]);
    return 0;
}
原文地址:https://www.cnblogs.com/zhangfengnick/p/5862591.html