【入门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\n",dp[1][n]); return 0; }