HDU 4939 Stupid Tower Defense(DP)

来源:互联网 发布:网上预约软件 编辑:程序博客网 时间:2024/04/29 21:25

题意略。

思路:可以看出把红塔放在最后面是最好的,因为放在最后面是更有可能得到更多的时间从而导致伤害最高,然后只要判断前面的塔就行了。比赛的时候觉得把绿塔放在最前面蓝塔放中间。。事实证明这样是不靠谱的。。dp[i][j]代表前i个有j个是蓝塔,对于前面j个蓝塔任意放在任何地方都对后面不产生影响,因为后面的时间变为t+j*z,然后绿塔的伤害为(j-i)*y,所以要dp[i][j]最优,所以是由dp[i-1][j-1]和dp[i-1][j]递推得到。递推完这个后,再进行一次n^2的递推目的是加上后面红塔的伤害,然后求得最大值。总复杂度是o(n^2)。

AC代码:

#include<cstdio>#include<ctype.h>#include<algorithm>#include<iostream>#include<cstring>#include<vector>#include<cstdlib>#include<stack>#include<cmath>#include<queue>#include<set>#include<ctime>#include<string.h>#include<string>using namespace std;#define ll __int64ll dp[1505][1505];int main(){    #ifdef GLQ    freopen("input.txt","r",stdin);//    freopen("o.txt","w",stdout);    #endif // GLQ    int n,i,j,t,cas=1;    ll x,y,z;    int T;    scanf("%d",&T);    while(T--)    {        scanf("%d%I64d%I64d%I64d%d",&n,&x,&y,&z,&t);        memset(dp,0,sizeof(dp));        for(i = 1; i <= n; i++)            for(j = 0; j <= i; j++)            {                if(i == j) continue;                dp[i][j] = dp[i-1][j]+y*((ll)t+z*j)*(ll)(i-j-1);//绿塔                if(j >= 1)                    dp[i][j] = max(dp[i][j],dp[i-1][j-1]+y*((ll)t+z*(j-1))*(ll)(i-j));//蓝塔//                cout<<i<<" "<<j<<" "<<dp[i][j]<<endl;            }        ll ans = n*t*x;        for(i = 1; i <= n; i++)            for(j = 0; j <= i; j++)                if(ans < dp[i][j] + (ll)(n-i)*(t+j*z)*(x+(i-j)*y))                {                    ans = dp[i][j] + (ll)(n-i)*(t+j*z)*(x+(i-j)*y);//                    cout<<ans<<endl;                }        printf("Case #%d: %I64d\n",cas++,ans);    }    return 0;}


0 0
原创粉丝点击