Fork me on GitHub

石子合并加强版

这里写图片描述
这里写图片描述

数据范围
对于 20%的数据,n=5
对于 60%的数据,n<=80
对于 100%的数据,n<=400

60分的做法:与石子合并一样,枚举起点,终点,第一个断点,第二个断点。时间复杂度O(n^4)。

100分做法:
用另一个数组f2[i][j]来优化,f2[][]是合并两堆最小(不过要用f[][]来更新),就可以降到O(n^4)。

#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdio>
#define LL long long
#define M 1000000000
using namespace std;
int n,a[409];
int f[409][409],f2[409][409],s[409];
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]),s[i]=s[i-1]+a[i];
    for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) f[i][j]=M,f2[i][j]=M;

    for(int i=n;i;i--)
    {
        f[i][i]=0;
        f[i][i+2]=s[i+2]-s[i-1];
        for(int j=i+3;j<=n;j++)
        {
            for(int k=i;k<j;k++)
             f2[i][j]=min(f2[i][j],f[i][k]+f[k+1][j]);
            for(int k=i;k<j;k++)
             f[i][j]=min(f[i][j],min(f[i][k]+f2[k+1][j],f2[i][k]+f[k+1][j])+s[j]-s[i-1]);
        }
    }
    printf("%d",f[1][n]);
    return 0;
}
posted @ 2017-09-24 17:48  primes  阅读(193)  评论(0编辑  收藏  举报