• [hdu7026]Might and Magic


    (以下默认$A_{0},D_{0},P_{0},K_{0}$都为非负整数)

    显然存活轮数$S=lceilfrac{H_{0}}{C_{p}max(A_{1}-D_{0},1)} ceil$​​​是一个关键的变量,且根据数论分块其仅有$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$​​​点的最大伤害值,显然有
    $$
    egin{cases}F_{p}(x)=C_{p}S_{p}max(x-D_{1},1)\F_{m}(x)=C_{m}egin{cases}lfloorfrac{x}{2} floor(x-lfloorfrac{x}{2} floor)&(lfloorfrac{x}{2} floorle S_{m})\S_{m}(x-S_{m})&(lfloorfrac{x}{2} floor>S_{m})end{cases}end{cases}
    $$
    最终答案即求$F(x)=F_{p}(x)+F_{m}(N'-x)$在$xin [0,N']$的最大值,不难证明$F_{p}$和$F_{m}$都是下凸的,进而将$F_{m}$翻转后和$F_{p}$求和仍是下凸的,也即$F$是下凸的

    同时,下凸函数的最大值显然在端点处取到,即$x=0$​​或$x=N'$​​,显然$x$也即$A_{0}$​,结论得证

    通过这个结论,对两类分别讨论:

    1.若$A_{0}=0$​,考虑再枚举$K_{0}$​,答案即​​
    $$
    egin{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}Smax(A_{0}-D_{1},1)$​​

    由于有$t$组数据,最终总复杂度为$o(tsqrt{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
    ",ans);
    30     } 
    31     return 0;
    32 } 
    View Code
  • 相关阅读:
    软件建模之UML图形讲解
    Android中级第八讲安卓子线程,以及定时任务使用讲解
    有你同行,我不会寂寞物联网操作系统Hello China后续开发计划及开发者征集
    物联网操作系统再思考Hello China操作系统的运营商网络协同机制
    Windows Phone 7 Storage
    Silverlight &Windows phone7 中使用Isolated Storage存储与读取图片
    Windows Phone7的Pivot控件简介
    windowsphone7的启动器和选择器
    如何将App的图标放到起始页面
    WebBrowser控件用法总结
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/15110511.html
Copyright © 2020-2023  润新知