Luogu P1880 [NOI1995]石子合并

(chy):DP其实挺简单的

(zzx):似乎是个水题】

(yxy):DP是啥

我真的不会写(DP)

[NOI1995]石子合并

区间(DP)。写了好久没写出来w

因为是个环,所以按照一个两倍长的链来处理。

(f[i][j])表示区间([i,j])的最优解。用前缀和维护区间和。

计算(f[i][j])的时候枚举一个断点位置,略暴力地求最优解。。

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#define MAXN 233
#define maxn -9999
#define minn 999999999
using namespace std;
int adp[MAXN][MAXN],bdp[MAXN][MAXN],a[MAXN],sum[MAXN]={};

int main()
{
    int n;
    scanf("%d",&n);
    
    for (int i=1;i<=(n<<1);i++)
    {
        for (int j=1;j<=(n<<1);j++)
        {
            adp[i][j]=minn;
            bdp[i][j]=maxn;
        }
    }
    
    for (int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        sum[i]=a[i]+sum[i-1];
        adp[i][i]=0;
        bdp[i][i]=0;
    }
    for (int i=n+1;i<=(n<<1);i++)
    {
        sum[i]=sum[i-1]+a[i-n];
        adp[i][i]=0;
        bdp[i][i]=0;
    }
    int end;
    for (int i=1;i<=n;i++)
    {
        for (int j=1;i+j<=(n<<1);j++)
        {
            end=i+j-1;
            for (int k=j;k<end;k++)
            {
                adp[j][end]=min(adp[j][end],adp[j][k]+adp[k+1][end]-sum[j-1]+sum[end]);
                bdp[j][end]=max(bdp[j][end],bdp[j][k]+bdp[k+1][end]-sum[j-1]+sum[end]);
            }
        }
    }
    int ansa=minn,ansb=maxn;
    for (int i=1;i<=n;i++)
    {
        ansa=min(ansa,adp[i][i+n-1]);
        ansb=max(ansb,bdp[i][i+n-1]);
    }
    printf("%d
%d",ansa,ansb);
    return 0;
}
(awsl)我不会写(DP)啊呜呜呜
原文地址:https://www.cnblogs.com/Kan-kiz/p/10795580.html