zoukankan      html  css  js  c++  java
  • [HNOI2017]大佬

    标签:DP+map(Hash)+单调性
    题解:

      觉得这道题很妙,题目说每天每天有那么多选择,但是其实只要不死,那么选择最大伤害可以枚举,而不死又可以DP。
      具体来说:首先要保证不死,那么我们设dp[i][j]代表在前i天,第i天的自信值为j,那么前i天中可以最多不刷题几天,也就是,可以用来打伤害。其实就相当于全部的状态都枚举出来的裸DP。
      做完这一步,我们取dp数组的最大值,也就是我最多有多少天可以使用。假设D天。
      在D天中,要选择3、4、5即可,剩下的天数,多退少补,执行1操作到正好即可。
      设两次怼大佬的情况分别为(d1,f1)、(d2,f2),即花费多少天打出多少伤害。假设大佬生命为HP,那么:
      HP-f1-f2>=0,否则大佬生命值就为负了,然后还要满足能打死,也就是HP-f1-f2<=D-d1-d2,也就是大佬剩下的生命我要能在剩余天数内执行1操作打完。
      当然这是怼两次的情况,怼一次就是HP-f1>=0 && HP-f1<=D-d1即可,不怼就是 HP>=0 && HP<=D即可。只要有符合条件的就是1.
      我们bfs+判重的枚举出所有可能的(d,f),然后以f为第一关键字,d为第二关键字排序。按照f从大到小的枚举第一次怼,然后发现这个是有单调性的:我们移项D>=HP-f1+d1-f2+d2,f1,d1是枚举的,那么自然-f1+d2最小即可。那么在满足f1+f2<=HP的条件下,增大f2,即指针向后扫,每次取-f1+d2最小,然后比较,O(状态数)扫过去即可。

     1 #include<queue>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<algorithm>
     6 #define LL long long
     7 #define pa pair<int,int>
     8 using namespace std;
     9 const int MAXN=2100000,mod=3587201;
    10 pa Q[MAXN];
    11 int n,m,mc,D,MAXC,tp,Maxsize;
    12 int dp[105][105],a[105],w[105],C[105];
    13 struct ed {int step,F,L;};
    14 queue<ed>Que;
    15 struct ED
    16 {
    17   struct gg{int x,y,Next;}edge[MAXN];
    18   int top,head[mod+5];
    19   void insert(int x,int y)
    20   {
    21     int tmp=((LL)x*100+y)%mod;
    22     edge[++top]=(gg){x,y,head[tmp]};head[tmp]=top;
    23   }
    24   bool query(int x,int y)
    25   {
    26     int tmp=((LL)x*100+y)%mod;
    27     for(int i=head[tmp];i;i=edge[i].Next)
    28       if(x==edge[i].x&&y==edge[i].y)return 1;
    29     return 0;
    30   }
    31 }map;//手写map,Hash判重
    32 inline int gi() { int res; scanf("%d",&res); return res; }
    33 void prepare()
    34 {
    35   for(int i=1;i<=n;i++)
    36     for(int j=a[i];j<=mc;j++)
    37       {
    38         dp[i][j-a[i]]=max(dp[i][j-a[i]],dp[i-1][j]+1);
    39         int tmp=min(mc,j-a[i]+w[i]);
    40         dp[i][tmp]=max(dp[i][tmp],dp[i-1][j]);
    41       }
    42   for(int i=1;i<=n;i++)
    43     for(int j=0;j<=mc;j++)
    44       D=max(D,dp[i][j]);
    45 }
    46 void bfs()
    47 {
    48   Que.push((ed){1,1,0});//初始状态:使用一天,打出1伤害,等级0。
    49   while(!Que.empty())
    50     {
    51       ed now=Que.front();
    52       Que.pop();
    53       if(now.step<D)
    54         {
    55           Que.push((ed){now.step+1,now.F,now.L+1});//加1等级
    56           if(now.L>1 && (LL)now.F*now.L<=(LL)MAXC && !map.query(now.F*now.L,now.step+1))//注意爆int,hash炸掉了也没事。
    57             {
    58               ed tmp=(ed){now.step+1,now.F*now.L,now.L};
    59               Que.push(tmp);
    60               Q[++tp]=(pa){tmp.F,tmp.step};//此处才加入队列,不能直接从Que取出来就加入,因为只加等级的状态是不优的,只有乘了,才更好。
    61               map.insert(tmp.F,tmp.step);
    62             }
    63         }
    64     }
    65 }
    66 int main()
    67 {
    68   freopen("dalao.in","r",stdin);
    69   freopen("dalao.out","w",stdout);
    70   n=gi();m=gi();mc=gi();
    71   for(int i=1;i<=n;i++)a[i]=gi();
    72   for(int i=1;i<=n;i++)w[i]=gi();
    73   for(int i=1;i<=m;i++)C[i]=gi(),MAXC=max(MAXC,C[i]);
    74   prepare();  bfs();
    75   sort(Q+1,Q+tp+1);
    76   for(int i=1;i<=m;i++)
    77     {
    78       if(C[i]<=D) {puts("1"); continue;}
    79       int flag=0,mi=0x3f3f3f3f;
    80       for(int j=tp,k=1;j>=1;j--)//按照单调性找是否有解。
    81         {
    82           while(k<tp && Q[k].first+Q[j].first<=C[i]) mi=min(mi,Q[k].second-Q[k].first) , k++;
    83           if(mi+Q[j].second-Q[j].first+C[i]<=D) {flag=1; break;}
    84           if(Q[j].first<=C[i] && C[i]-Q[j].first+Q[j].second<=D) {flag=1; break;}
    85         }
    86       printf("%d
    ",flag);
    87     }
    88   return 0;
    89 }
  • 相关阅读:
    django框架的models
    图像的特征提取
    laravel框架学习
    机器学习--Classifier comparison
    java中的静态变量---static
    初次编程经历
    TERSUS笔记员工信息513-Tersus表格中勾选框升级处理
    TERSUS笔记员工信息512-Tersus勾选框全选和全不选的三种设定方法(转载+补充)
    TERSUS笔记员工信息511-Mysql查询
    TERSUS笔记员工信息510-css文字超出显示
  • 原文地址:https://www.cnblogs.com/D-O-Time/p/7953435.html
Copyright © 2011-2022 走看看