• [BZOJ2964]Boss单挑战


    题目描述

    (RPG)游戏中,最后一战是主角单挑(Boss),将其简化后如下:

    主角的气血值上限为(HP),魔法值上限为(MP),愤怒值上限为(SP)(Boss)仅有气血值,其上限为(M)

    现在共有(N)回合,每回合都是主角先行动,主角可做如下选择之一:

    1. 普通攻击:减少对方(X)的气血值,并增加自身(DSP)的愤怒值。(不超过上限)

    2. 法术攻击:共有(N1)种法术,第(i)种消耗(B_i)的魔法值,减少对方(Y_i)的气血值。(使用时要保证(MP)不小于(B_i)

    3. 特技攻击:共有(N2)种特技,第(i)种消耗(C_i)的愤怒值,减少对方(Z_i)的气血值。(使用时要保证(SP)不小于(C_i)

    4. 使用(HP)药水:增加自身(DHP)的气血值。(不超过上限)

    5. 使用(MP)药水:增加自身(DMP)的魔法值。(不超过上限)

    之后(Boss)会攻击主角,在第(i)回合减少主角(A_i)的气血值。

    刚开始时气血值,魔法值,愤怒值都是满的。当气血值小于等于({0})时死亡。

    如果主角能在这(N)个回合内杀死(Boss),那么先输出“(Yes)”,之后在同一行输出最早能在第几回合杀死(Boss)。(用一个空格隔开)

    如果主角一定会被(Boss)杀死,那么输出“(No)”。

    其它情况,输出“(Tie)”。

    Input

    输入的第一行包含一个整数(T),为测试数据组数。

    接下来(T)部分,每部分按如下规则输入:

    第一行九个整数(N,M,HP,MP,SP,DHP,DMP,DSP,X)

    第二行(N)个整数(A_i)

    第三行第一个整数(N_1),接下来包含(N_1)对整数(B_i,Y_i)

    第四行第一个整数(N_2),接下来包含(N_2)对整数(C_i,Z_i)

    对于第一个样例,主角的策略是:第一回合法术攻击,第二回合使用(HP)药水,第三回合特技攻击,第四回合普通攻击。
    对于(10\%)的数据:(N≤10,N1=N2=0)
    对于(30\%)的数据:(N≤10,N1=N2=1)
    对于(60\%)的数据:(N≤100,M≤10000,HP,MP,SP≤70)
    对于(100\%)的数据:(1≤N≤1000,1≤M≤1000000,1≤HP,MP,SP≤1000,N1,N2≤10,DHP,A_i≤HP,DMP,B_i≤MP)(DSP,C_i≤SP,X,Y_i,Z_i≤10000,1≤T≤10)

    Output

    输出共包含(T)行,每行依次对应输出一个答案。

    Sample Input

    2
    5 100 100 100 100 50 50 50 20
    50 50 30 30 30
    1 100 40
    1 100 40
    5 100 100 100 100 50 50 50 10
    50 50 30 30 30
    1 100 40
    1 100 40
    

    Sample Output

    Yes 4
    Tie
    

    很显然是一道(DP)题,但由于状态数以及转移方式太多了,导致我们无法直接(DP)

    那就要考虑是否能将这些分开来考虑,它们之间是否有严格的约束关系

    我们可以发现,在对战中,魔法攻击和特效攻击只与总回合数有关。

    那我们就把这两个变量分开来进行类似于背包的(DP),最后在把血量放到背包里进行(DP)即可。

    (dp[i][j])表示前(i)个回合,血量为(j)能攻击的回合数。

    若某一时刻的回合数达到了击杀最小回合数就可以击杀了。

    (dpm[i][j])表示(i)个回合,魔法值剩余(j)造成的最大伤害。

    (dps[i][j])表示(i)个回合,愤怒值剩余(j)造成的最大伤害,注意,愤怒值补充时会造成伤害。

    (Fmp[i])表示(i)个回合造成的最大魔法伤害。

    (Fsp[i])表示(i)个回合造成的最大特殊伤害。

    代码如下

    #include <cstdio>
    #include <cstring>
    #include <queue>
    #include <iostream>
    #include <algorithm>
     
    using namespace std;
     
    #define LL long long
    #define u64 unsigned long long
    #define reg register
    #define Raed Read
    #define debug(x) cerr<<#x<<" = "<<x<<endl;
    #define rep(a,b,c) for(reg int a=(b),a##_end_=(c); a<=a##_end_; ++a)
    #define ret(a,b,c) for(reg int a=(b),a##_end_=(c); a<a##_end_; ++a)
    #define drep(a,b,c) for(reg int a=(b),a##_end_=(c); a>=a##_end_; --a)
    #define erep(i,G,x) for(reg int i=(G).Head[x]; i; i=(G).Nxt[i])
     
    inline int Read() {
        int res = 0, f = 1;
        char c;
        while (c = getchar(), c < 48 || c > 57)if (c == '-')f = 0;
        do res = (res << 3) + (res << 1) + (c ^ 48);
        while (c = getchar(), c >= 48 && c <= 57);
        return f ? res : -res;
    }
     
    template<class T>inline bool Min(T &a, T const&b) {
        return a > b ? a = b, 1 : 0;
    }
    template<class T>inline bool Max(T &a, T const&b) {
        return a < b ? a = b, 1 : 0;
    }
     
    const int N = 1e3+5, M = 1e3+5, mod = 1e9 + 9;
     
    bool MOP1;
     
    int n,m,hp,mp,sp,dhp,dmp,dsp,x,n1,n2,A[N],b[N],c[N],bb[N],cc[N];
     
    struct T3100 {
        int dp[N][M],Fmp[M],Fsp[M],dpm[N][M],dps[N][M];
        inline void solve(void) {
            rep(i,1,n)rep(j,0,mp)dpm[i][j]=0;
            rep(i,1,n)rep(j,0,sp)dps[i][j]=0;
            rep(i,0,n)Fsp[i]=Fmp[i]=0;
            rep(i,0,n) {
                rep(j,0,mp)Max(Fmp[i],dpm[i][j]);
                rep(j,0,mp) {
                    Max(dpm[i+1][min(j+dmp,mp)],dpm[i][j]);
                    rep(k,1,n1)if(b[k]<=j)Max(dpm[i+1][j-b[k]],dpm[i][j]+bb[k]);
                }
            }
            rep(i,0,n) {
                rep(j,0,sp)Max(Fsp[i],dps[i][j]);
                rep(j,0,sp) {
                    Max(dps[i+1][min(j+dsp,sp)],dps[i][j]+x);
                    rep(k,1,n2) if(c[k]<=j)Max(dps[i+1][j-c[k]],dps[i][j]+cc[k]);
                }
            }
            int Ans=n+n;
            rep(i,0,n)rep(j,0,n)if(Fsp[i]+Fmp[j]>=m)Min(Ans,i+j);
            memset(dp,-63,sizeof dp);
            dp[1][hp]=1;
            rep(i,1,n) {
                rep(j,1,hp) {
                    if(dp[i][j]>=Ans) {
                        printf("Yes %d
    ",(int)i);
                        return;
                    }
                    if(A[i]<min(j+dhp,hp))Max(dp[i+1][min(j+dhp,hp)-A[i]],dp[i][j]);
                    if(A[i]<j)Max(dp[i+1][j-A[i]],dp[i][j]+1);
                }
            }
            rep(i,1,hp)if(dp[n+1][i]>=0) {
                puts("Tie");
                return;
            }
            puts("No");
        }
    } P100;
     
    bool MOP2;
     
    inline void _main(void) {
        int T=Read();
        while(T--) {
            n=Read(),m=Read(),hp=Read(),mp=Read(),sp=Read(),dhp=Raed(),dmp=Read(),dsp=Raed(),x=Read();
            rep(i,1,n)A[i]=Read();
            n1=Read();
            rep(i,1,n1)b[i]=Read(),bb[i]=Read();
            n2=Read();
            rep(i,1,n2)c[i]=Raed(),cc[i]=Read();
            P100.solve();
        }
    }
     
    signed main() {
    #define offline1
    #ifdef offline
        freopen("boss.in", "r", stdin);
        freopen("boss.out", "w", stdout);
        _main();
        fclose(stdin);
        fclose(stdout);
    #else
        _main();
    #endif
        return 0;
    }
    
  • 相关阅读:
    egret-使用URLLoader 设置不同的dataFormat 加载不同的资源
    egret新手指南--自定义组件
    事件的三个阶段
    事件派发,事件机制
    屏幕适配
    断线重连机制
    电影屏幕字从天上掉下来的效果
    使用select2 实现select多选与初始化数据。
    ul高度为0 li高度为0
    php生成json文件,以zip压缩包批量下载。
  • 原文地址:https://www.cnblogs.com/dsjkafdsaf/p/11276871.html
Copyright © 2020-2023  润新知