石子合并问题(区间DP)
http://acm.nankai.edu.cn/p1137.html
区间DP
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#define inf (1<<26)
#define ll __int64
#define nMAX 205
using namespace std;
int sum[nMAX],dpm[nMAX][nMAX],dpM[nMAX][nMAX];
int a[nMAX],n;
int min(int a,int b)
{
return a<b?a:b;
}
int max(int a,int b)
{
return a>b?a:b;
}
int main()
{
int i,j,k;
while(~scanf("%d",&n))
{
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
a[i+n]=a[i];
}
for(i=1;i<=2*n;i++)
{
for(j=i+1;j<=2*n;j++)
{
dpm[i][j]=inf;
dpM[i][j]=-inf;
}
}
sum[0]=0;
for(i=1;i<=2*n;i++)
{
sum[i]=sum[i-1]+a[i];
dpm[i][i]=dpM[i][i]=0;
}
for(k=1;k<n;k++)
{
for(i=1;i+k<2*n;i++)
{
for(j=0;j<k;j++)
{
dpM[i][i+k]=max(dpM[i][i+k],dpM[i][i+j]+dpM[i+j+1][i+k]+sum[i+k]-sum[i-1]);
dpm[i][i+k]=min(dpm[i][i+k],dpm[i][i+j]+dpm[i+j+1][i+k]+sum[i+k]-sum[i-1]);
}
}
}
int MIN=inf,MAX=-inf;
for(i=1;i<n;i++)
{
MIN=min(MIN,dpm[i][i+n-1]);
MAX=max(MAX,dpM[i][i+n-1]);
//cout<<"a,b="<<dpm[i][i+n-1]<<" "<<dpM[i][i+n-1]<<endl;
//cout<<"MAX,MIN="<<MAX<<" "<<MIN<<endl;
}
printf("%d\n%d\n",MIN,MAX);
}
return 0;
}

浙公网安备 33010602011771号