zoukankan      html  css  js  c++  java
  • [noip模拟题]LGTB 玩THD

      LGTB 最近在玩一个类似DOTA 的游戏名叫THD
      有一天他在守一座塔,对面的N 个小兵排成一列从近到远站在塔前面
    每个小兵有一定的血量hi,杀死后有一定的金钱gi
      每一秒,他都可以攻击任意一个活着的小兵,对其造成P 点伤害,如果小兵的血量低于1 点,小兵死亡,他
    得到金钱。他也可以不攻击任何小兵。
      每一秒LGTB 攻击完毕之后,塔会攻击距离塔最近的一个活着的小兵,对其造成Q 点伤害,如果小兵的血
    量低于1 点,小兵死亡,LGTB 不会得到金钱
      现在LGTB 想知道,在他选择最优策略时,他能得到多少钱。
    输入
    输入第一行包含3 个整数P, Q, N
    接下来N 行,每行包含2 个整数hi, gi
    第i 个小兵和塔之间的距离为i
    输入的意义如题面所示
    对于20% 的数据,$1 leqslant N leqslant 4$
    对于50% 的数据,$1 leqslant N leqslant 20$
    对于100% 的数据,$20 leqslant P, Q leqslant 200$, $1 leqslant N leqslant 100$, $1 leqslant h_{i} leqslant 200$, $1 leqslant g_{i} leqslant 10^{6}$
    输出
    输出包含一个整数W,代表LGTB 最多能获得的金钱
    样例
    样例输入样例输出
    20 60 3
    80 100
    80 200
    120 300
    500
    4


      假如我们要得到第$i$个士兵的收益,我们可以贪心地让塔打小兵尽量多的次数,然后让LGTB去补刀。当然这样不一定一次能打死,所以需要在补刀之前还需打上几次。

      所以用$f[i][j]$表示当前考虑到第$i$个士兵时(前面的士兵已经被消灭了),当前积攒了$j$次攻击机会时的最大收益,

      第一种操作是不管这个小兵,那么直接让塔把它打死,那么就可以得到一些攻击机会。

      第二种操作是在塔把它打残后补刀,这样会消耗一些攻击机会,同时会得到一些收益。

    Code

     1 #include<iostream>
     2 #include<fstream>
     3 #include<cstring>
     4 using namespace std;
     5 ifstream fin("thd.in");
     6 ofstream fout("thd.out");
     7 typedef class xb{
     8     public:
     9         int money;                                        //钱数 
    10         int health;                                        //生命值 
    11         int kill;
    12         int pkill;
    13 }xb;
    14 int p,q,n;
    15 xb *xbs;
    16 int f[101][1001];
    17 istream& operator >>(istream& in, xb& x){
    18     in>>x.health>>x.money;
    19 }
    20 int main(){
    21     fin>>p>>q>>n;
    22     xbs = new xb[(const int)(n + 1)];
    23     for(int i = 1; i <= n; i++){
    24         fin>>xbs[i];
    25         xbs[i].kill = ( xbs[i].health - 1 )/q;                    //塔把士兵i打成残血的次数 
    26         xbs[i].pkill = ( xbs[i].health - xbs[i].kill * q - 1)/p + 1;    //塔把士兵打成残血后,玩家打死士兵的次数 
    27     }
    28     for(int i = 0;i <= n;i++){                    //f数组初始化 
    29         for(int j =0; j <= 1000;j++){
    30             f[i][j] = -1000000;
    31         }
    32     }
    33     f[0][1] = 0;                           34                                          
    35     for(int i = 1; i <= n;i++){
    36         for(int j = 0;j <= 1000;j++){
    37             f[i][j + xbs[i].kill + 1] = max(f[i - 1][j], f[i][j + xbs[i].kill + 1]);
    38             if(j >= xbs[i].pkill - xbs[i].kill){
    39                 f[i][j - (xbs[i].pkill - xbs[i].kill)] = max(f[i - 1][j] + 
    40                     xbs[i].money, f[i][j - (xbs[i].pkill - xbs[i].kill)]);
    41             }
    42         }
    43     }
    44     int maxv = f[n][0];
    45     for(int i = 0;i <= 1000;i++)
    46         maxv = max(f[n][i], maxv);
    47     fout<<maxv;
    48     return 0;
    49 }


     

  • 相关阅读:
    Error: Client network socket disconnected before secure TLS connection was established
    python对文章词频的统计
    IntelliJ IDEA创建java空项目
    java提取docx文件中的图片
    vue v-for 循环复选框-默认勾选第一个的实现方法
    nodejs的request创建的get和post请求,带参数
    python list转换字符串报错TypeError: sequence item 0: expected str instance, int found
    linux常用命令
    ES9(2018) 正则表达式命名捕获组
    ESLint+Prettier代码规范实践
  • 原文地址:https://www.cnblogs.com/yyf0309/p/5671918.html
Copyright © 2011-2022 走看看