[hdu7026]Might and Magic
(以下預設$A_{0},D_{0},P_{0},K_{0}$都為非負整數)
顯然存活輪數$S=\lceil\frac{H_{0}}{C_{p}\max(A_{1}-D_{0},1)}\rceil$是一個關鍵的變數,且根據數論分塊其僅有$o(\sqrt{H_{0}})$種取值,不妨利用數論分塊直接$o(\sqrt{H_{0}})$列舉,進而也可以確定$D_{0}$(取對應的最小值即可)
(上取整的數論分塊實際上即將$H_{0}-1$即可)
進一步的,有以下結論:存在一種取到最值的方案,滿足$A_{0}=0$或$A_{0}=N'$
關於證明,考慮再列舉這$S$輪中物理攻擊和魔法攻擊的輪數,即$S_{p}$和$S_{m}$(其中$S_{p}+S_{m}=S$)
接下來,考慮如何分配物理攻擊和魔法攻擊的點數,令$F_{p}(x)$和$F_{m}(x)$分別為給物理攻擊和魔法攻擊分配$x$點的最大傷害值,顯然有
$$
\begin{cases}F_{p}(x)=C_{p}S_{p}\max(x-D_{1},1)\\F_{m}(x)=C_{m}\begin{cases}\lfloor\frac{x}{2}\rfloor(x-\lfloor\frac{x}{2}\rfloor)&(\lfloor\frac{x}{2}\rfloor\le S_{m})\\S_{m}(x-S_{m})&(\lfloor\frac{x}{2}\rfloor>S_{m})\end{cases}\end{cases}
$$
最終答案即求$F(x)=F_{p}(x)+F_{m}(N'-x)$在$x\in [0,N']$的最大值,不難證明$F_{p}$和$F_{m}$都是下凸的,進而將$F_{m}$翻轉後和$F_{p}$求和仍是下凸的,也即$F$是下凸的
同時,下凸函式的最大值顯然在端點處取到,即$x=0$或$x=N'$,顯然$x$也即$A_{0}$,結論得證
通過這個結論,對兩類分別討論:
1.若$A_{0}=0$,考慮再列舉$K_{0}$,答案即
$$
\begin{cases}C_{p}(S-K_{0})+C_{m}K_{0}(N'-K_{0})&(K_{0}<S)\\C_{m}S(N'-K_{0})&( K_{0}\ge S)\end{cases}
$$
(為了保證魔法攻擊不劣於物理攻擊,可以令$K_{0}<N'$,但實際上也會在下面的情況中考慮)
即是一個關於$K_{0}$的分段一次和二次函式, 不難求極值
2.若$A_{0}=N'$,顯然全部使用物理攻擊,答案即$C_{p}S\max(A_{0}-D_{1},1)$
由於有$t$組資料,最終總複雜度為$o(t\sqrt{H_{0}})$,可以通過
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 int t,Cp,Cm,H0,A1,D1,n; 5 ll ans; 6 ll f(ll a,ll b,ll c,int x){ 7 return a*x*x+b*x+c; 8 } 9 ll get_max(ll a,ll b,ll c,int l,int r){ 10 ll pos=-b/(a<<1),ans=max(f(a,b,c,l),f(a,b,c,r)); 11 if ((l<=pos)&&(pos<=r))ans=max(ans,f(a,b,c,pos)); 12 if ((l<=pos+1)&&(pos+1<=r))ans=max(ans,f(a,b,c,pos+1)); 13 return ans; 14 } 15 int main(){ 16 scanf("%d",&t); 17 while (t--){ 18 scanf("%d%d%d%d%d%d",&Cp,&Cm,&H0,&A1,&D1,&n); 19 ans=0; 20 for(int i=1,j;i<=A1;i=j+1){ 21 if (i>=H0)j=A1; 22 else j=min((H0-1)/((H0-1)/i),A1); 23 int S=((H0+i-1)/i+Cp-1)/Cp,D0=A1-j,nn=n-D0; 24 if (nn<0)continue; 25 if (min(nn,S)>1)ans=max(ans,get_max(-Cm,(ll)Cm*nn-Cp,(ll)Cp*S,1,min(nn,S)-1)); 26 if (S<nn)ans=max(ans,(ll)Cm*S*(nn-S)); 27 ans=max(ans,(ll)Cp*S*max(nn-D1,1)); 28 } 29 printf("%lld\n",ans); 30 } 31 return 0; 32 }View Code