石子合并(一)

来源:互联网 发布:java开源社区有哪些 编辑:程序博客网 时间:2024/04/30 09:15

石子合并(一)

时间限制:1000 ms  |  内存限制:65535 KB
难度:3
描述
    有N堆石子排成一排,每堆石子有一定的数量。现要将N堆石子并成为一堆。合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费的代价为这两堆石子的和,经过N-1次合并后成为一堆。求出总的代价最小值。
输入
有多组测试数据,输入到文件结束。
每组测试数据第一行有一个整数n,表示有n堆石子。
接下来的一行有n(0< n <200)个数,分别表示这n堆石子的数目,用空格隔开
输出
输出总代价的最小值,占单独的一行
样例输入
31 2 3713 7 8 16 21 4 18
样例输出
9239

思路:

floyd式动规, dp[i][j]从i到j堆合并所需代价。

#include <stdio.h>#include <string.h>#include <stdlib.h>int dp[202][202], sum[202];int min(int a, int b){return a < b ? a : b;}int main(){int n, i, s, k, e, temp;while(scanf("%d", &n) != EOF){memset(dp, 0, sizeof(dp));                    //初始化dpsum[0] = 0;for(i = 1; i <= n; i++){scanf("%d", &temp);sum[i] = sum[i-1]+temp;                    //记录区间总数}for(i = 2; i <= n; i++)                       //弗洛伊德类似算法, i长度, s起点, e终点{for(s = 1; s+i-1 <= n; s++){e = s+i-1;dp[s][e] = 0xfffffff;                  //第一次比较设为最大值for(k = s; k < e; k++)                 {dp[s][e] = min(dp[s][e], dp[s][k] + dp[k+1][e]);}dp[s][e] += (sum[e]-sum[s-1]);         //合并后加上两堆之和}}printf("%d\n", dp[1][n]);}return 0;}


0 0
原创粉丝点击