思路:首先红色肯定要放在最后面。前面蓝色和绿色dp求解。
dp[i][j] 表示前面(i+j) 个 有 i 个蓝色塔 j个绿色塔 能造成最大伤害。
//============================================================================ // Name : 1005.cpp // Author : // Version : // Copyright : Your copyright notice // Description : Hello World in C++, Ansi-style //============================================================================ #include <iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cstring> #include<vector> #define LL long long #define MAXN 1505 using namespace std; LL dp[MAXN][MAXN]; LL max(LL x,LL y) { return x>y?x:y; } int main() { int tt,ri=0; LL n,x,y,z,t; scanf("%d",&tt); while(tt--) { LL ans=0; scanf("%I64d%I64d%I64d%I64d%I64d",&n,&x,&y,&z,&t); memset(dp,0,sizeof(dp)); for(int i=0;i<=n;++i)//blue { for(int j=0;j+i<=n;++j)//green { LL k=n-i-j; LL v=z*i+t; LL tmp=dp[i][j]+k*v*x+k*v*y*j;//剩下后面补上红色 ans=max(tmp,ans); LL add=v*y*j;// 加一个 蓝色绿色对于当前格子都没影响,影响只来源于前面的。 dp[i+1][j]=max(dp[i+1][j],dp[i][j]+add); dp[i][j+1]=max(dp[i][j+1],dp[i][j]+add); } } printf("Case #%d: %I64d ",++ri,ans); } return 0; }