题目链接
朴素算法就能过,求最大求最小都能做
一种是一本通的写法(枚举起点终点),还可以采用区间DP枚举区间长度
枚举点
#include<cstdio>
#include<cstring>
#include<algorithm>
#define INF 0x3f3f3f3f
using namespace std;
int sum[110],f[110][110];
int main()
{
//freopen("in.txt","r",stdin);
int n,i,j,k,x;
while(scanf("%d",&n)!=EOF)
{
for(i=1;i<=n;i++)
{
scanf("%d",&x);
sum[i]=sum[i-1]+x;
}
memset(f,0x3f,sizeof(f));
for(i=1;i<=n;i++)f[i][i]=0;
for(i=n-1;i>=1;i--)
for(j=i+1;j<=n;j++)
for(k=i;k<=j-1;k++)
f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]+sum[j]-sum[i-1]);
printf("%d ",f[1][n]);
memset(f,0,sizeof(f));
for(i=n-1;i>=1;i--)
for(j=i+1;j<=n;j++)
for(k=i;k<=j-1;k++)
f[i][j]=max(f[i][j],f[i][k]+f[k+1][j]+sum[j]-sum[i-1]);
printf("%d\n",f[1][n]);
}
return 0;
}
枚举区间长
//区间DP
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,x,sum[110],dp[110][110];
int main()
{
//freopen("in.txt","r",stdin);
while(scanf("%d",&n)!=EOF)
{
memset(dp,0x3f,sizeof(dp));
sum[0]=0;
int i,j,k,len;
for(i=1;i<=n;i++)
{
scanf("%d",&x);
sum[i]=sum[i-1]+x;
dp[i][i]=0;
}
for(len=1;len<n;len++)
for(i=1;i<=n-len;i++)
{
j=i+len;
for(k=i;k<j;k++)
dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]);
dp[i][j]+=sum[j]-sum[i-1];
}
printf("%d ",dp[1][n]);
memset(dp,0,sizeof(dp));
for(i=1;i<=n;i++)dp[i][i]=0;
for(len=1;len<n;len++)
for(i=1;i<=n-len;i++)
{
j=i+len;
for(k=i;k<j;k++)
dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]);
dp[i][j]+=sum[j]-sum[i-1];
}
printf("%d\n",dp[1][n]);
}
return 0;
}