nyoj 737 石子合并(一) 【区间dp】

来源:互联网 发布:冰川网络股票股吧 编辑:程序博客网 时间:2024/05/08 11:39

石子合并(一)

时间限制: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


注意单独一堆是不用付出代价的,然后就是裸的区间dp了。区间dp真有意思。。。


AC代码:

 #include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#include <algorithm>#include <queue>#include <stack>#include <map>#include <set>#include <vector>#include <string>#define INF 0x3f3f3f3f#define eps 1e-8#define MAXN (200+10)#define MAXM (500000)#define Ri(a) scanf("%d", &a)#define Rl(a) scanf("%lld", &a)#define Rf(a) scanf("%lf", &a)#define Rs(a) scanf("%s", a)#define Pi(a) printf("%d\n", (a))#define Pf(a) printf("%.2lf\n", (a))#define Pl(a) printf("%lld\n", (a))#define Ps(a) printf("%s\n", (a))#define W(a) while(a--)#define CLR(a, b) memset(a, (b), sizeof(a))#define MOD 1000000007#define LL long long#define lson o<<1, l, mid#define rson o<<1|1, mid+1, r#define ll o<<1#define rr o<<1|1#define PI acos(-1.0)using namespace std;int a[MAXN], dp[MAXN][MAXN];int sum[MAXN];int DFS(int i, int j){    if(dp[i][j] != -1) return dp[i][j];    if(i >= j) return 0;    dp[i][j] = INF;    for(int k = i; k <= j; k++)        dp[i][j] = min(dp[i][j], DFS(i, k) + DFS(k+1, j) + sum[j] - sum[i-1]);    return dp[i][j];}int main(){    int n;    while(Ri(n) != EOF)    {        sum[0] = 0;        for(int i = 1; i <= n; i++)            Ri(a[i]), sum[i] = sum[i-1] + a[i];        CLR(dp, -1);        Pi(DFS(1, n));    }    return 0;}        



0 0
原创粉丝点击