【Watery DP】[Dota1002]光之守卫(Gandolf)

描述

光之守卫不想打辅助了……于是他想去打ROSHAN….

我们为了光之守卫不死……就假设ROSHAN不会攻击……
光之守卫有两种攻击方式:
1:普通攻击
2:冲击波(需要蓄气)
由于大家还需要光之守卫来打辅助,所以光之守卫只有N的时间来打ROSHAN
对于每一个时刻i,光之守卫有三种选择:
1:普通攻击(如果之前在蓄气,那么蓄的气就白费了)
2:蓄气(可连续蓄气,不能超过5个时刻)
3:冲击波(前提是前一秒钟在蓄气)
在第i时刻,如果光之守卫攻击的话,可以造成a[i]的伤害
在第i时刻,如果光之守卫放冲击波的话,可以造成b[i]*k的伤害(k为之前连续蓄气的时间)
光之守卫想知道,在N的时间内,他最多可以对ROSHAN造成多少伤害?

输入

第一行,一个数N
第二行,N个数,表示a[i]
第三行,N个数,表示b[i]

输出

一个数,即最大总伤害

样例输入

5
1 2 3 4 5
5 4 3 2 1

样例输出

16

提示

N<=1000000
0<=a[i],b[i]<=100000

【Solution】

F[i,t]表示第i个时刻,蓄气了t秒所造成的最大伤害。那么F[i,0]表示的就是这一秒进行物理普通攻击或者放波。

F[i,0]←max{F[i-1,0]+a[i],F[i-1,t]+b[i]*t(F[i-1,t]被更新过and t<>0)}

F[i,t](1=<t<=5)←F[i-1,t-1]

就是这样,嗯。

【Code】

  1: Program Gandalf(input,output);
  2:   var a,b:array[1..1000000]of longint;
  3:       F:array[0..1000001,-1..5]of longint;
  4:       i,t,n,ans:longint;
  5:   Function max(a,b:Longint):longint;
  6:     begin if a>b then exit(a) else exit(b);end;
  7:   Function min(a,b:Longint):longint;
  8:     begin if a<b then exit(a) else exit(b);end;
  9:   begin
 10:     readln(n);
 11:     for i:=1 to n do read(a[i]);readln;
 12:     for i:=1 to n do read(b[i]);
 13:     fillchar(f,sizeof(f),$ff);F[0,0]:=0;
 14:     for i:=1 to n do
 15:       for t:=0 to min(i,5) do
 16:         begin
 17:           F[i,0]:=max(F[i,0],F[i-1,t]+a[i]);
 18:           if(F[i-1,t]<>-1)and(t<>0)then
 19:             F[i,0]:=max(F[i,0],F[i-1,t]+b[i]*t);
 20:           if t<>0 then F[i,t]:=F[i-1,t-1];
 21:         end;
 22:     ans:=F[n,0];
 23:     for t:=1 to 5 do if F[n,t]>ans then ans:=F[n,t];
 24:     writeln(ans);
 25:   end.
原文地址:https://www.cnblogs.com/Loongint/p/2195535.html