NewTrain 1 T5: Boss Single Challenge

Keywords: PHP

Topic analysis

(Seeing this kind of ridiculous question, it's usually either greedy or DP...)

We found that there were too many states to be greedy about this problem, so we had to do DP.

Because magic attack is relatively independent from ordinary attack and special attack, it can be considered separately.

Let fm[i],fs[i] be the maximum damage that can be caused by using only magic attack and ordinary attack and special attack to the end of turn I (regardless of life or death).

Then make gm[i][j],gs[i][j] respectively to the end of the first round (end), magic power / anger value remaining J point can cause the greatest damage (regardless of my life or death).

Then, for each fm[i] and fs[i], update the answer once.

Consider how to maintain gm[i][j],gs[i][j].

There are two operations:

1. Recovery mana/rage.

2. Use skills.

Transfer separately.

 

Consider how to get the final answer. First, let's figure out that Boss can be killed in at least a few rounds, no matter whether it's alive or dead.

Let dp[i][j] represent the maximum of the total number of skills used + offensives at the end of Round I, with a blood volume of J.

There are also two operations:

1. Restore Health

2. Use a Skill/General Attack

Transfer separately.

If a dp[i][j] reaches the minimum number of rounds mentioned above, it means that Boss can be killed by adopting the optimal strategy at this time, and the answer can be output directly.

 

So how to judge a draw?

If there is data in the i+1 round, it means that we can live to the i+1 round and output Tie.

Otherwise, you will lose.

 1 #include<bits/stdc++.h>
 2 #define INTMAX 2147483647LL
 3 #define PII pair<int,int>
 4 #define MK make_pair
 5 #define re register
 6 #define clr(x) memset(x,0,sizeof(x))
 7 using namespace std;
 8 typedef long long ll;
 9 const double Pi=acos(-1.0);
10 const int Inf=0x3f3f3f3f;
11 const int MAXN=1e3+10;
12 inline int read(){
13     re int x=0,f=1,ch=getchar();
14     while(!isdigit(ch))f=ch=='-'?-1:1,ch=getchar();
15     while(isdigit(ch))x=x*10+ch-48,ch=getchar();
16     return x*f;
17 }
18 inline ll readll(){
19     re ll x=0,f=1,ch=getchar();
20     while(!isdigit(ch))f=ch=='-'?-1:1,ch=getchar();
21     while(isdigit(ch))x=x*10+ch-48,ch=getchar();
22     return x*f;
23 }
24 
25 int T,n,m,hp,mp,sp,dhp,dmp,dsp,mp_cnt,sp_cnt,x;
26 int a[MAXN],ump[MAXN],vmp[MAXN],usp[MAXN],vsp[MAXN];
27 int fm[MAXN],gm[MAXN][MAXN],fs[MAXN],gs[MAXN][MAXN],dp[MAXN][MAXN];
28 inline void Up(int &x,int y){if(x<y) x=y;}
29 inline void Solve(){
30     clr(fm);clr(gm);clr(fs);clr(gs);
31     n=read();m=read();hp=read();mp=read();sp=read();dhp=read();dmp=read();dsp=read();x=read();
32     for(int i=1;i<=n;++i) a[i]=read();
33     mp_cnt=read();for(int i=1;i<=mp_cnt;++i) ump[i]=read(),vmp[i]=read();
34     sp_cnt=read();for(int i=1;i<=sp_cnt;++i) usp[i]=read(),vsp[i]=read();
35     for (int i=0;i<=n;++i){
36         for(int j=0;j<=mp;++j) Up(fm[i],gm[i][j]);
37         if(i<n)
38             for(int j=0;j<=mp;++j){
39                 Up(gm[i+1][min(mp,j+dmp)],gm[i][j]);
40                 for(int k=1;k<=mp_cnt;++k)
41                     if(j>=ump[k])
42                         Up(gm[i+1][j-ump[k]],gm[i][j]+vmp[k]);
43             }
44     }
45     for(int i=0;i<=n;++i){
46         for(int j=0;j<=sp;++j) Up(fs[i],gs[i][j]);
47         if(i<n)
48             for(int j=0;j<=sp;++j){
49                 Up(gs[i+1][min(sp,j+dsp)],gs[i][j]+x);
50                 for(int k=1;k<=sp_cnt;++k)
51                     if(j>=usp[k])
52                         Up(gs[i+1][j-usp[k]],gs[i][j]+vsp[k]);
53             }
54     }
55     int mn=Inf;
56     for(int i=0;i<=n;++i)
57         for(int j=0;j<=n;++j)
58             if(fm[i]+fs[j]>=m)
59                 mn=min(mn,i+j);
60     memset(dp,192,sizeof(dp));
61     dp[1][hp]=1;
62     for(int i=1;i<=n;++i){
63         for(int j=1;j<=hp;++j){
64             if(dp[i][j]>=mn){
65                 printf("Yes %d\n",i);
66                 return;
67             }
68         }
69         for(int j=1;j<=hp;++j){
70             if(min(hp,j+dhp)>a[i]) Up(dp[i+1][min(hp,j+dhp)-a[i]],dp[i][j]);
71             if(j>a[i]) Up(dp[i+1][j-a[i]],dp[i][j]+1); 
72         }
73     }
74     for(int i=1;i<=hp;++i)
75         if(dp[n+1][i]>=0){
76             puts("Tie");return;
77         }
78     puts("No");
79 }
80 int main(){
81     T=read();
82     while(T--) Solve();
83     return 0;
84 }

Posted by sunil.23413 on Sun, 28 Jul 2019 08:42:13 -0700