您的位置:首页 > 其它

zjnu 1275 最大的算式(Bigexp)(区间DP)

2015-10-28 21:14 453 查看
题目链接:

http://acm.zjnu.edu.cn/CLanguage/showproblem?problem_id=1275

思路:

典型的区间DP。

因为数据范围比较小,所以就开了3维。

设dp[i][j][k]为i~j区间上添加了k个乘号的最大值。

那么就有转移方程:

dp[i][j][k]=max(dp[i][l][m]+dp[l+1][j][k-m],dp[i][l][m]*dp[l+1][j][k-m-1])。

代码:

#include<stdio.h>
#include<string.h>
#define ll __int64
ll max(ll a,ll b)
{
return a>b?a:b;
}
int main()
{
ll N,K,i,j,k,a[20],dp[20][20][20],sum[20];
scanf("%I64d%I64d",&N,&K);

for(i=1;i<=N;i++)
scanf("%I64d",&a[i]);
memset(dp,0,sizeof(dp));
memset(sum,0,sizeof(sum));
for(i=1;i<=N;i++)
{sum[i]=sum[i-1]+a[i];
dp[i][i][0]=a[i];
}
for(k=0;k<=K;k++)
{
for(int l=2;l<=N;l++)
{
for(i=1;i<=N-l+1;i++)
{
int zhong=i+l-1;
for(j=i;j<zhong;j++)
{
for(int m=0;m<=k;m++)
{
if(m<k)
dp[i][zhong][k]=max(dp[i][zhong][k],max(dp[i][j][m]+dp[j+1][zhong][k-m],dp[i][j][m]*dp[j+1][zhong][k-m-1]));
else dp[i][zhong][k]=max(dp[i][zhong][k],dp[i][j][m]+dp[j+1][zhong][k-m]);
}

}
}
}
}

printf("%I64d\n",dp[1]
[K]);

}


刚开始以为是邮局问题,就是设了dp[i][j]代表前i个数字里面添加了j个乘号。然后顺利的写出了转移方程:dp[i][j]=max(dp[i][j],dp[k][j-1]*sum[k][i])。但是交上去却Wa了,后来发现有一组样例过不了:

3 1

2 0 0

正确答案应该是2*(0+0)=2,然而我的代码出来是0。模拟了过程后发现,原来这样的方式是不能进行a*(b+c)的操作的,因为我一开始就把dp[i][0]=sum[1][i],也就是将前i个数字套上括号了。= = 。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: