传送门

这个思路很妙诶->这里

以下为了方便,我把自信说成血量好了

虽然表面上看起来每一天有很多种选择,然而我们首先要保证的是不死,然后考虑不死的情况下最多能拿出多少天来进行其他操作。不死可以dp,最大伤害可以枚举

首先我们要保证不死。设$dp[i][j]$表示在第$i$天,血量为$j$时最多多少天不刷题,那么这个可以直接dp出来

我们设$D$为dp数组的最大值,即最多有多少天可以使用

在这$D$天里,我们只需要选3,4,5操作,剩下的就可以多退少补

我们假设两次怼大佬的情况分别为$(d1,f1),(d2,f2)$其中$d$表示需要花费几天,$f$表示能打掉多少血

那么$f1+f2<=HP$,否则大佬生命值就为负的了,还得满足$HP-f1-f2<=D-d1-d2$,也就是说剩下的血要能在剩余的天数内执行操作$1$打完

同理,如果怼一次的话就是$f1<=HP$且$HP-f1<=D-d1$,不怼的话就是$HP>=0,HP<=D$

那么我们可以用dfs+判重枚举出所有的$(d,f)$,然后以$f$为第一关键字,$d$为第二关键字排序,移项,发现要满足$D>=HP-f1+d1-f2+d2$,我们可以枚举$(f1,d1)$,然后发现这$f$是有单调性的,那么就可以弄一个指针在那里扫,然后记录一下满足$f2+f1<=HP$的最小的$-f2+d2$,那么可以O(状态数)通过此题

 //minamoto
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define ll long long
using namespace std;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1=buf,*p2=buf;
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,:;}
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,:;}
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getc()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getc());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
const int N=,mod=;
pair<int,int> Q[N];
int n,m,mc,D,MAXC,tp,Maxsize;
int dp[][],a[],w[],C[];
struct ed{int step,F,L;};
queue<ed> Que;
struct ED{
int ver[N],Next[N],head[mod+],edge[N],tot;
inline void insert(int u,int v){
int tmp=((ll)u*+v)%mod;
ver[++tot]=u,Next[tot]=head[tmp],head[tmp]=tot,edge[tot]=v;
}
inline bool query(int u,int v){
int tmp=((ll)u*+v)%mod;
for(int i=head[tmp];i;i=Next[i])
if(u==ver[i]&&v==edge[i]) return true;
return false;
}
}map;
//手写map,hash判重
void init(){
for(int i=;i<=n;++i)
for(int j=a[i];j<=mc;++j){
cmax(dp[i][j-a[i]],dp[i-][j]+);
int tmp=min(mc,j-a[i]+w[i]);
cmax(dp[i][tmp],dp[i-][j]);
}
for(int i=;i<=n;++i)
for(int j=;j<=mc;++j)
cmax(D,dp[i][j]);
}
void bfs(){
Que.push((ed){,,});//初始状态:使用一天,打出1伤害,等级0。
while(!Que.empty()){
ed now=Que.front();Que.pop();
if(now.step<D){
Que.push((ed){now.step+,now.F,now.L+});//加1等级
if(now.L>&&(ll)now.F*now.L<=(ll)MAXC&&!map.query(now.F*now.L,now.step+)){
//注意加longlong防止爆int,但哈希炸了也没事
//下面不用加longlong是因为MAXC在int范围内,如果小于肯定没超
ed tmp=(ed){now.step+,now.F*now.L,now.L};
Que.push(tmp);
Q[++tp]=make_pair(tmp.F,tmp.step);
//此处才加入队列,不能直接从Que取出来就加入,因为只加等级的状态是不优的,只有乘了,才更好。
map.insert(tmp.F,tmp.step);
}
}
}
}
int main(){
//freopen("testdata.in","r",stdin);
n=read(),m=read(),mc=read();
for(int i=;i<=n;++i) a[i]=read();
for(int i=;i<=n;++i) w[i]=read();
for(int i=;i<=m;++i) C[i]=read(),cmax(MAXC,C[i]);
init(),bfs();
sort(Q+,Q++tp);
for(int i=;i<=m;++i){
if(C[i]<=D){puts("");continue;}//按照单调性找是否有解。
int flag=,mn=0x3f3f3f3f;
for(int j=tp,k=;j;--j){
while(k<tp&&Q[k].first+Q[j].first<=C[i]) cmin(mn,Q[k].second-Q[k].first),++k;
if(mn-Q[j].first+Q[j].second+C[i]<=D){flag=;break;}
if(Q[j].first<=C[i]&&C[i]-Q[j].first+Q[j].second<=D){flag=;break;}
}
printf("%d\n",flag);
}
return ;
}

洛谷P3724 [AH2017/HNOI2017]大佬(决策单调性)的更多相关文章

  1. 洛谷 P3723 [AH2017/HNOI2017]礼物 解题报告

    P3723 [AH2017/HNOI2017]礼物 题目描述 我的室友最近喜欢上了一个可爱的小女生.马上就要到她的生日了,他决定买一对情侣手环,一个留给自己,一个送给她.每个手环上各有 \(n\) 个 ...

  2. 洛谷 P3721 - [AH2017/HNOI2017]单旋(LCT)

    洛谷题面传送门 终于调出来这道题了,写篇题解( 首先碰到这样的题我们肯定要考虑每种操作会对树的形态产生怎样的影响: 插入操作:对于 BST 有一个性质是,当你插入一个节点时,其在 BST 上的父亲肯定 ...

  3. 洛谷 P5897 - [IOI2013]wombats(决策单调性优化 dp+线段树分块)

    题面传送门 首先注意到这次行数与列数不同阶,列数只有 \(200\),而行数高达 \(5000\),因此可以考虑以行为下标建线段树,线段树上每个区间 \([l,r]\) 开一个 \(200\times ...

  4. P3724 [AH2017/HNOI2017]大佬

    传送门 发现保持自信和做其他事情互不干扰,可以直接做一次 $dp$ 求出最多能空出几天来怼大佬 然后就变成给你若干天,是否能怼死大佬,考虑求出所有的 天数和输出的嘲讽值集合,因为天数不多,嘲讽值增长很 ...

  5. 洛谷P3722 [AH2017/HNOI2017]影魔(线段树)

    题意 题目链接 Sol 题解好神仙啊qwq. 一般看到这种考虑最大值的贡献的题目不难想到单调数据结构 对于本题而言,我们可以预处理出每个位置左边第一个比他大的位置\(l_i\)以及右边第一个比他大的位 ...

  6. 洛谷P3721 [AH2017/HNOI2017]单旋(线段树 set spaly)

    题意 题目链接 Sol 这题好毒瘤啊.. 首先要观察到几个性质: 将最小值旋转到根相当于把右子树变为祖先的左子树,然后将原来的根变为当前最小值 上述操作对深度的影响相当于右子树不变,其他的位置-1 然 ...

  7. 洛谷P3726 [AH2017/HNOI2017]抛硬币(组合数+扩展Lucas)

    题面 传送门 题解 果然--扩展\(Lucas\)学了跟没学一样-- 我们先考虑\(a=b\)的情况,这种情况下每一个\(A\)胜的方案中\(A\)和\(B\)的所有位上一起取反一定是一个\(A\)败 ...

  8. 洛谷P3723 [AH2017/HNOI2017]礼物(FFT)

    传送门 首先,两个数同时增加自然数值相当于只有其中一个数增加(此增加量可以小于0) 我们令$x$为当前的增加量,${a},{b}$分别为旋转后的两个数列,那么$$ans=\sum_{i=1}^n(a_ ...

  9. 洛谷P3723 [AH2017/HNOI2017]礼物

    吴迪说他化学会考上十分钟就想出来了,太神了%%%不过我也十分钟 但是调了一个多小时啊大草 懒得人话翻译了,自己康吧: 我的室友(真的是室友吗?)最近喜欢上了一个可爱的小女生.马上就要到她的生日了,他决 ...

随机推荐

  1. git教程(远程仓库和管理分支)

    在github上新建了一个仓库,然后相与本地的仓库联系起来 $ Git remote add origin https://github.com/liona329/learngit.git fatal ...

  2. 线程安全(1)--demo1

    成员变量的类用于多线程时是不安全的,不安全体现在这个成员变量可能发生非原子性的操作,而变量定义在方法内也就是局部变量是线程安全的.想想在使用struts1时,不推荐创建成员变量,因为action是单例 ...

  3. js防止重复点击

    表单元素 disabled 没有之一. el.prop('disabled', true); ajax({}).done(function() { el.prop('disabled', false) ...

  4. 目录扫描工具-Dirsearch

    下载项目,并打开 ┌─[root@sch01ar]─[/sch01ar] └──╼ #git clone https://github.com/maurosoria/dirsearch ┌─[root ...

  5. Ubuntu登录异常: 输入正确的密码, 但是却无法进入系统, 总是返回到登录界面, 但是用ctrl+alt+F1-F文字界面登录都可以进入。

    今天打开电脑的时候, 在输入密码之后, 未进入ubuntu的桌面, 而是显示了几行英文之后有返回到了登录界面.显示的英文如下: could not write bytes: Broken pipe   ...

  6. java 多线程系列基础篇(七)之线程休眠

    1. sleep()介绍 sleep() 定义在Thread.java中.sleep() 的作用是让当前线程休眠,即当前线程会从“运行状态”进入到“休眠(阻塞)状态”.sleep()会指定休眠时间,线 ...

  7. 类型:Java;问题:eclipse配置maven;结果:eclipse配置maven

    eclipse配置maven 下面跟大家分享的是eclipse配置maven的方法. 方法/步骤 安装maven之前,要先安装jdk及配置JAVA_HOME环境变量.JDK1.4以上. 下载maven ...

  8. c# 代码调用ssis包

    https://docs.microsoft.com/en-us/sql/integration-services/run-manage-packages-programmatically/loadi ...

  9. leetcode633

    用开方的思想来解题. bool judgeSquareSum(int c) { int h = pow(c, 0.5); ; i <= h; i++) { ), 0.5); if (left - ...

  10. MyBatis总结六:resultMap详解(包含多表查询)

    简介: MyBatis的每一个查询映射的返回类型都是ResultMap,只是当我们提供的返回类型属性是resultType的时候,MyBatis对自动的给我们把对应的值赋给resultType所指定对 ...