P1880 【[NOI1995]石子合并】

又是一道简单的水题

这道题没有代码构思的难度,就只是一道模版题,只是连接成了一个环而已。

下面献上本蒟蒻的代码。

本蒟蒻用的是递推式和三重循环,时间复杂度为O(n^3)

#include <cstdio>
#include <iostream>
/*头文件*/
using namespace std;
int a[210],f[210][210],s[210][210];
/*a数组是各堆的数量,f数组是最大值,s数组是最小值*/
int main(){
    int n,Max,Min;
    scanf("%d",&n);//输入
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        a[n+i]=a[i];//化线为链
    }
    for(int i=1;i<=2*n;i++)a[i]=a[i]+a[i-1];//前缀和
    for(int r=2;r<=n;r++){//枚举起始点
        for(int i=1;i<=2*n-r+1;i++){//左端点
            int j=i+r-1;右端点
            f[i][j]=f[i+1][j]+a[j]-a[i-1];
            s[i][j]=s[i+1][j]+a[j]-a[i-1];
            /*先给初始值*/
            for(int k=i;k<j;k++){
                f[i][j]=max(f[i][j],f[i][k]+f[k+1][j]+a[j]-a[i-1]);
                s[i][j]=min(s[i][j],s[i][k]+s[k+1][j]+a[j]-a[i-1]);
                /*动态转换方程*/
            }
        }
    }
    Max=f[1][n],Min=s[1][n];
    for(int i=2;i<=n;i++){
        if(f[i][i+n-1]>Max)Max=f[i][i+n-1];
        if(s[i][i+n-1]<Min)Min=s[i][i+n-1];
    }
    /*取n个表中的最大值*/
    printf("%d\n%d",Min,Max);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_42926515/article/details/82936713