2018-2019 ACM-ICPC, Asia East Continent Finals I. Misunderstood … Missing

Source title: the Click
meaning of the questions: A is your current attack, D represents the increment to the beginning of each round A, A and D are initialized to zero.
Alternatively three operations each time.
1. attack resulted in A + a [i] injury.
2. do not attack but that the increase D b [i].
3. do not attack but increase of the A c [i].
Q. maximum damage.

Is able to see the beginning of a topic dp, but how to represent a state, if the forward has three states for each operation, and will change the AD, since a [i], b [i ], c [i] range are large, no way to store the array. But we can find only select 1 monster is attacked, the other two operations are carried out on the A lifting. This state can start from the number of attacks is fully represented at most 100 attack. And the last option must be attacked, just start from the reverse, but also for the initial A 0.
Option 1: Direct plus a [i]
Option 2: So if the first j (j> i) rounds attacked if JI b [i]
Option 3: after i the total number of attacks k
c [i]
but the choice of 2 we need know which several rounds carried out the attack, [(j1 + j2 + ... jn) -k * i] * b [i] is the damage caused. Can (j1 + j2 + ... jn) 1 to 100 as the standard state since 5050 at most.
Would write the state transition equation DP [i] [j] [k] represents a sum of subscript j attack times j times k after the first attack of operations i i.
Since only dp [i] [] [] and dp [i + 1] [] [], there may also be used to optimize the space-saving rolling array.

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<map>
#include<algorithm>
#include<queue>
#define MAX_len 50100*4
using namespace std;
typedef long long  ll;
ll a[110],b[110],c[110];
/*
如果是第一种情况:
那么+a[i]
第二种情况
那么 (sum-i*j)*b[i]
第三种情况
那么j*c[i]
*/
ll dp[2][110][6000];// i:当前的回合 j:该回合后攻击的次数 k:之后攻击的下标总和
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n,i,j,k;
        memset(dp,0,sizeof(dp));
        scanf("%d",&n);
        for(i=1;i<=n;i++)
           cin>>a[i]>>b[i]>>c[i];
        dp[n%2][1][n]=a[n];
        for(i=n-1;i>=1;i--)//倒推回合
        {
            for(j=n-i;j>=1;j--)//该回合后的攻击次数
            {
                ll MAX=(n+n-j+1)*j/2;
                for(k=n;k<=MAX;k++)
                {
                    dp[i%2][j+1][k+i]=max(dp[(i+1)%2][j][k]+a[i],dp[i%2][j+1][k+i]);
                    dp[i%2][j][k]=max(dp[i%2][j][k],dp[(i+1)%2][j][k]+(k-j*i)*b[i]);
                    dp[i%2][j][k]=max(dp[i%2][j][k],dp[(i+1)%2][j][k]+j*c[i]);
                }
            }
            memset(dp[(i+1)%2],0,sizeof(dp[(i+1)%2]));
        }
        ll ans=0;
        for(i=1;i<=n;i++)
			for(j=1;j<=5050;j++)
				ans=max(ans,dp[1][i][j]);
				printf("%lld\n",ans);
    }
    return 0;
}
Published 72 original articles · won praise 19 · views 7509

Guess you like

Origin blog.csdn.net/weixin_43958964/article/details/104124990