CF1396C Monster Invaders 题解
首先有一个结论,每个人向前走只会走 \(1\) 格,走更多不会更优。感觉应该是挺好证的。然后接下来就可以考虑 dp,设 \(dp_i\) 表示搞完了 \([1,i]\) 的所有 boss,现在在 \(i+1\) 位置的最小时间。有三种转移:
-
用手枪一个一个打小怪,用狙击枪打boss,走到下一关
-
用手枪打到boss或者用第二种枪一气打一遍,走到前面再走回来,用手枪打死 boss,走到下一关
-
boss还是剩一滴,然后前面那个也把boss打到剩一滴,然后两个都打死 boss,走到下一关
直接线性 dp 即可,最后人一定会停在 \(n\) 或 \(n-1\),统计答案即可。
点击查看代码
const int N=1e6+13;
int n;
ll a[N],r1,r2,r3,d,dp[N];
int main(){
read(n),read(r1),read(r2),read(r3),read(d);
for(int i=1;i<=n;++i) read(a[i]);
memset(dp,0x3f,sizeof dp);dp[0]=0;
for(int i=1;i<=n;++i){
dp[i]=min(dp[i],dp[i-1]+r1*a[i]+r3+d);
dp[i]=min(dp[i],dp[i-1]+min(r1*(a[i]+1),r2)+d+d+r1+d);
if(i>=2) dp[i]=min(dp[i],dp[i-2]+min(r1*(a[i-1]+1),r2)+d+min(r1*(a[i]+1),r2)+d+r1+d+r1+d);
}
println(min(dp[n]-d,dp[n-2]+min(r1*(a[n-1])+1,r2)+d+r1*a[n]+r3+d+r1));
return 0;
}