正题
题目链接:https://www.luogu.com.cn/problem/P4922
题目大意
题目好长直接放了
在崩坏 3 中有一个叫做天命基地的地方,女武神们将在基地中开派对与敌人们厮杀。
女武神们的攻击力为 atkatkatk,她们将进行资源保卫战!
天命基地中有 111个 boss,boss 的血量为 hphphp,boss 不会攻击女武神。
现在有一条长度为 nnn 的道路,道路的一头是 boss,另外一头是女武神需要保卫的资源,最开始 boss 每秒将会向资源移动 1 个单位长度。女武神们需要保护资源,所以她们要攻击 boss。
我们将整条道路分成 nnn 个格子,最开始资源在第 nnn 格,女武神在第 111 格,boss 在第 000 格。
因为女武神的手太短了,所以只有当 boss 到达女武神当前那一格的时候,女武神才会攻击 boss,攻击完之后女武神会后退一格。
女武神有以下 888 种攻击方式(每一格只能使用一种攻击方式)
- 技能,造成 80%atk80\% atk80%atk 的伤害,并使 boss 获得 111 层燃烧 buff,在之后的每秒钟额外受到 10%atk10\% atk10%atk 的伤害。(燃烧buff可以叠加)
- 闪避,造成 70%atk70\% atk70%atk 的伤害,并使 boss 时间暂停 5s5s5s。(5s5s5s 内 boss 无法移动且仍会受到燃烧伤害)
- 大招,造成 120%atk120\% atk120%atk 的伤害,使 boss 时间暂停 5s5s5s。
- 分支攻击,造成 70%atk70\% atk70%atk 的伤害,并使 boss 时空减速,使 boss 经过每一个格子的时间增加 1s1s1s。
- 爱酱的炸弹,使 boss 获得 111 层燃烧 buff,并使 boss 愤怒,移速 +50%+50\%+50%。
- 犹大的誓约,造成 60%atk60\% atk60%atk 的伤害,如果 boss 有燃烧 buff 则减少 1 层,使 boss 时间暂停 4s4s4s。
- 奥托之光,造成 10%atk10\% atk10%atk 的伤害,如果 boss 有燃烧 buff 则清除 buff,使 boss 时间暂停 10s10s10s。
- 律者之力,造成 80%atk80\% atk80%atk 的伤害,使 boss 的移动速度 +100%+100\%+100%。
现在给你所有的信息,让你帮助 disangan233 蒟蒻算一下,他的女武神能否在 boss 触碰到资源前战胜 boss。
如果可以,输出 boss 死亡时距离资源最远的格子编号。如果不可以,请输出对 boss 造成的最大伤害。
对于 100%100\%100% 的数据,保证:
n≤10,000atk≡0(mod10)atk≤10,000maxAtk≤264−1n\leq 10,000 \qquad atk\equiv 0(\bmod\ 10)\qquad atk\leq 10,000\qquad \max Atk\leq 2^{64}-1 n≤10,000atk≡0(mod 10)atk≤10,000maxAtk≤264−1
解题思路
快三年之前的比赛上面写的题了,那时候只会写O(n3)O(n^3)O(n3)的dpdpdp。(什么一雪前耻)
首先有很多技能一看就是没有用的,有用的只有技能(叠燃烧),分支攻击(叠减速),大招。
然后大招一定是最后放的,还有一个就是nnn的范围好像是可以O(n2)O(n^2)O(n2)卡一下的。
设fi,jf_{i,j}fi,j表示到前iii次,jjj层燃烧,然后剩下i−ji-ji−j层就是减速了。
这样dpdpdp就好了,时间复杂度O(n2)O(n^2)O(n2)因为j≤ij\leq ij≤i所以常数是12\frac{1}{2}21
code
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll unsigned long long
using namespace std;
const ll N=11000;
ll n,hp,atk,maxs,mins,f[2][N];
signed main()
{scanf("%lld%lld%lld",&n,&hp,&atk);atk/=10ull;if(!atk)return printf("0\nMiHoYo Was Destroyed!");mins=n;for(ll i=0;i<n;i++){for(ll j=0;j<=i;j++){ll k=i-j+1;//燃烧j层 减速k层 maxs=max(maxs,f[i&1][j]+atk*j*(n-i)*(5ull+k)+(n-i)*atk*12ull);mins=min(mins,i+(hp-f[i&1][j]+(j*5ull+j*k+12ull)*atk-1)/(j*5ull+j*k+12ull)/atk);f[~i&1][j+1]=max(f[~i&1][j+1],k*j*atk+atk*8ull+f[i&1][j]);//叠燃烧f[~i&1][j]=max(f[~i&1][j],k*j*atk+atk*7ull+f[i&1][j]);//叠减速 }}if(maxs>=hp)printf("%lld\nTech Otakus Save The World!",mins);else printf("%lld\nMiHoYo Was Destroyed!",maxs);return 0;
}