很经典的一个DP题目,没接触过区间DP的时候老师就拿这个当例子说过。
同石子合并差不多,因为是个环形的,所以就直接在序列后面接一个相同序列,完成环的功能。
状态转移方程dp[i][j] = max(dp[i][j],dp[i][k]+dp[k+1][j]+a[i].s*a[k].e*a[j].e),开始把dp[i][k]和dp[k+1][j]之间的运算搞成了乘法一直都很大,调试很久没发现错误...后面看看题目推算才知道自己犯傻了。
不用结构体那么方程就变为了dp[i][j] = max(dp[i][j],dp[i][k]+dp[k+1][j]+a[i]*a[k+1]*a[j+1])
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define INF 0x7fffffff
long long dp[405][405];
int a[405];
long long max(long long x,long long y)
{
if(x>y)
return x;
return y;
}
int main()
{
long long i,j,n;
while(scanf("%lld",&n)!=EOF)
{
memset(dp,0,sizeof(dp));
for(i=1;i<=n;i++)//环形
{
scanf("%d",&a[i]);
a[i+n]=a[i];
}
for(int v=1;v<2*n;v++)
{
for(int i=1;i<2*n-v;i++)
{
int j = i + v;
for(int k=i;k<j;k++)
dp[i][j] = max(dp[i][j],dp[i][k]+dp[k+1][j]+a[i]*a[k+1]*a[j+1]);
}
}
long long m=0;
for(i=1;i<=n;i++)
m=max(dp[i][i+n-1],m);
printf("%lld\n",m);
}
return 0;
}