zoukankan      html  css  js  c++  java
  • NewTrain1 T5: Boss单挑战

    题目分析

    (看到这种打怪的题,一般不是贪心就是DP...)

    我们发现对于此题,状态太多以至于无法贪心,所以我们只好DP。

    因为 魔法攻击 与 普通攻击和特技攻击 是相对独立的,所以可以分开来考虑。

    令fm[i],fs[i]分别为 只使用魔法攻击 与 只是用普通攻击和特技攻击 到第i回合(结束)所能造成伤害的最大值(先不管本人死活)。

    再令 gm[i][j],gs[i][j]分别为到了第i回合(结束),魔法量/愤怒值剩下j点所能造成的最大伤害(先不管本人死活)。

    那么对于每个 fm[i]与fs[i] 扫一遍更新答案。

    考虑如何维护gm[i][j],gs[i][j]。

    有两种操作:

         1.回复魔法值/愤怒值。

         2.使用技能。

    分别转移即可。

    考虑如何得出最终答案,首先我们先求出不论死活的情况下,最少几回合可以杀掉Boss。

    令dp[i][j] 表示到了第i回合(结束),血量为j, 使用的技能+普攻总数的最大值。

    同样有两种操作:

         1.回复生命值

         2.使用一次技能/普攻

    分别转移即可。

    若某个dp[i][j]达到了上面所说的最少回合数,那么说明此时采取最优策略的话已经可以把Boss杀死了,那么可以直接输出该答案。

    那么如何判断平局呢?

    如果第i+1轮有数据,就说明可以活到i+1轮,就输出Tie。

    反之则必输。

     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
    ",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 }
  • 相关阅读:
    第二十九课 循环链表的实现
    第二十八课 再论智能指针(下)
    第二十七课 再论智能指针(上)
    第二十六课 典型问题分析(Bugfix)
    普通new和placement new的重载
    leetcode 581. Shortest Unsorted Continuous Subarray
    leetcode 605. Can Place Flowers
    leetcode 219. Contains Duplicate II
    leetcode 283. Move Zeroes
    leetcode 217. Contains Duplicate
  • 原文地址:https://www.cnblogs.com/LI-dox/p/11261527.html
Copyright © 2011-2022 走看看