出处:NOI1995普及组 RQNOJ490
一次AC,没什么好说的,注意细节就好,第一个下标从大到小循环,第二个下表从小到大循环且不超过n。
#include<stdio.h>
#include<iostream>
using namespace std;
const int N=200;
const int INF=0x3fffffff;
int main()
{
int n,i,j,k,maxs,mins;
int dp1[N][N],dp2[N][N],a[N],sum[N];
while (~scanf("%d",&n))
{
sum[0]=0;
for (i=1;i<=n;i++)
{
scanf("%d",a+i);
a[i+n]=a[i];
sum[i]=sum[i-1]+a[i];
}
for (i=n+1;i<n+n;i++) sum[i]=sum[i-1]+a[i];
for (i=0;i<n+n;i++) for (j=0;j<n+n;j++) dp1[i][j]=dp2[i][j]=0;
for (i=n+n;i>0;i--)
{
for (j=i+1;j<i+n&&j<n+n;j++)
{
maxs=-1,mins=INF;
for (k=i;k<j;k++)
{
maxs=(dp1[i][k]+dp1[k+1][j])>maxs?dp1[i][k]+dp1[k+1][j]:maxs;
mins=(dp2[i][k]+dp2[k+1][j])<mins?dp2[i][k]+dp2[k+1][j]:mins;
}
dp1[i][j]=maxs+sum[j]-sum[i-1];
dp2[i][j]=mins+sum[j]-sum[i-1];
}
}
/* for (i=1;i<=n;i++)
{
for (j=i;j<i+n;j++)
{
printf("%d ",dp2[i][j]);
}
printf("\n");
}*/
for (i=1,maxs=0,mins=INF;i<=n;i++)
{
maxs=dp1[i][i+n-1]>maxs?dp1[i][i+n-1]:maxs;
mins=dp2[i][i+n-1]<mins?dp2[i][i+n-1]:mins;
}
printf("%d\n%d\n",mins,maxs);
}
return 0;
}