[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 }