Nyoj 737 石子合并(一)

来源:互联网 发布:ubuntu php集成环境 编辑:程序博客网 时间:2024/04/30 16:09

石子合并问题,就是矩阵链连乘的一个推广,或者说是变形,因此矩阵链连乘,是一个根基,需要理解透彻 。

因此可参考矩阵链连乘:http://blog.csdn.net/hearthougan/article/details/25834141

#include <iostream>#include <cstring>#include <cstdio>#include <cmath>using namespace std;const int MAXN = 210;const int INF = 0xffffff;int dp[MAXN][MAXN];int sum[MAXN];void Find_Ans(int n){    int num, i, j, k;    for(num = 2; num <= n; ++num)    {        for(i = 1; i <= n-num+1; ++i)        {            j = i + num - 1;            dp[i][j] = INF;            for(k = i; k <= j-1; ++k)                dp[i][j] = min(dp[i][j], dp[i][k] + dp[k+1][j] + sum[j] - (i > 1 ? sum[i-1] : 0));        }    }    return ;}int main(){    int n;    int i;    while(~scanf("%d", &n))    {        memset(sum, 0, sizeof(sum));        memset(dp, 0, sizeof(dp));        for(i = 1; i <= n; ++i)        {            scanf("%d", &sum[i]);            sum[i] += sum[i-1];        }        Find_Ans(n);        printf("%d\n", dp[1][n]);    }    return 0;}

GarsiaWachs算法:

#include <iostream>#include <cstdio>#include <cstring>using namespace std;const int MAXN = 50010;int s[MAXN], t, ans;void Comebine_Stone(int k){    int i;    int tmp = s[k] + s[k-1];    ans += tmp;    for(i = k; i <= t-2; ++i)        s[i] = s[i+1];    t--;    for(i = k-1; i > 0 && s[i-1] < tmp; --i)        s[i] = s[i-1];    s[i] = tmp;    while(i >= 2 && s[i] >= s[i-2])    {        int d = t - i;        Comebine_Stone(i-1);        i = t - d;    }}int main(){    int i, n;    while(~scanf("%d", &n))    {        memset(s, 0, sizeof(s));        for(i = 0; i < n; ++i)            scanf("%d", &s[i]);        t = 1, ans = 0;        for(i = 1; i < n; ++i)        {            s[t++] = s[i];            while(t >= 3 && s[t-3] <= s[t-1])                Comebine_Stone(t-2);        }        while(t > 1)            Comebine_Stone(t-1);        printf("%d\n", ans);    }    return 0;}


0 0
原创粉丝点击