正解:dp+bfs

解题报告:

传送门!

这题看起来很复杂的样子其实真的很复杂

但是仔细看一下题目,会发现其实操作只有两个目的嘛,一个是保证自己不死,一个是让对手减血

而且保证自己不死只有一种操作

而且这种操作和其他东西都麻油关系,不管多少血量,不管你前面的操作是哪些,反正加的血量是一样的

所以考虑把这两个分开来思考

首先求血量

考虑到要留尽量多的时间让对手减血,而对于攻击对手这个事儿来说,无论哪天攻击造成的伤害都是相等的,对于具体日期麻油要求,看到这样子就要想到dp了嘛(具体日期无影响鸭QAQ

所以设状态f[i][j]:第i天血量为j,最多不用刷题(也就是涨血)几天

转移很简单嘛,普通背包

然后取dp中的max,也就是最多能用来攻击对手的时间D

接下来考虑攻击对手

首先肯定是要么345组合拳要么1,相当于只有两种

设用345的两次方案分别是(d1,h1)(d2,h2),表示积累d天伤害为h

再设对手的血量为HP

然后如果要战胜对手,首先不能血量为负,所以h1+h2<=HP

又要活下去,所以HP-h1-h2<=D-d1-d2

然后上面是攻击两次嘛,如果攻击一次相当于有一组=(0,0)就好,不攻击就是两组都=(0,0)就好

然后就做完了

然后说下具体做法

首先就枚举状态昂,bfs枚举出所有可能的状态,然后把这些状态按h为第一关键字d为第二关键字地排序

然后对h从大到小地枚举第一次攻击

第二次攻击,可以先对上面的式子移项,得D>=HP-h1-h2+d1+d2

又h1d1其实是已知式,所以就是D>=T+d2-h2

如果有合法方案就说明对手会死嘛,所以要努力让它合法,就是说要努力保证d2-h2合法

但还有一个要求昂,就h1+h2<=HP

所以就在满足h1+h2<=HP的条件下,增大h2(即指针向后扫),每次取(-h2+d2)min,然后比较,O(状态数)扫过去就好

然后另外有个小细节就是这里有个手写hash

但是很简单,简单的hash思想+链式前向星思想就好,不想多说,自己看代码就好QAQ

#include<bits/stdc++.h>
using namespace std;
#define il inline
#define rg register
#define gc getchar()
#define mp make_pair
#define fr first
#define sc second
#define int long long
#define rp(i,x,y) for(rg int i=x;i<=y;++i)
#define my(i,x,y) for(rg int i=x;i>=y;--i)
#define e(i,x) for(rg int i=head[x];i;i=edge[i].nxt) const int N=+,M=+,mod=;
int n,m,mc,a[N],w[N],c[N],f[N][N],dmx,mxc,zt_cnt;
pair<int,int>zt[M];
struct node{int f,l,d;};
struct hsh
{
struct ed{int x,y,nxt;}edge[M];
int head[mod+],cnt;
void push(int x,int y){int pos=(1ll*x*+y)%mod;edge[++cnt]=(ed){x,y,head[pos]};head[pos]=cnt;}
bool query(int x,int y){int pos=(1ll*x*+y)%mod;e(i,pos)if(edge[i].x==x&&edge[i].y==y)return true;return false;}
}mapp; il int read()
{
char ch=gc;int x=;bool y=;
while(ch!='-' && (ch>'' || ch<''))ch=gc;
if(ch=='-')ch=gc,y=;
while(ch>='' && ch<='')x=(x<<)+(x<<)+(ch^''),ch=gc;
return y?x:-x;
}
il void dp()
{
rp(i,,n)
rp(j,a[i],mc)
{
f[i][j-a[i]]=max(f[i-][j]+,f[i][j-a[i]]);
f[i][min(j-a[i]+w[i],mc)]=max(f[i-][j],f[i][min(j-a[i]+w[i],mc)]);
}
rp(i,,n)rp(j,,mc)dmx=max(dmx,f[i][j]);
}
il void bfs()
{
queue<node>Q;Q.push((node){,,});
while(!Q.empty())
{
node tmp=Q.front();Q.pop();
if(tmp.d==dmx)continue;
Q.push((node){tmp.f,tmp.l+,tmp.d+});
if(tmp.l> && 1ll*tmp.f*tmp.l<=mxc && !mapp.query(tmp.f*tmp.l,tmp.d+))
{
Q.push((node){1ll*tmp.f*tmp.l,tmp.l,tmp.d+});
zt[++zt_cnt]=mp(1ll*tmp.f*tmp.l,tmp.d+);
mapp.push(tmp.f*tmp.l,tmp.d+);
}
}
}
il void wk(int hp)
{
if(hp<=dmx)return void(printf("1\n"));
int mn=1e9;int k=;
my(j,zt_cnt,)
{
while(k<zt_cnt && zt[k].fr+zt[j].fr<=hp)mn=min(mn,zt[k].sc-zt[k].fr),++k;
if(mn+hp-zt[j].fr+zt[j].sc<=dmx)return void(printf("1\n"));
if(zt[j].fr<=hp && hp-zt[j].fr<=dmx-zt[j].sc)return void(printf("1\n"));
}
printf("0\n");
} main()
{
// freopen("dl.in","r",stdin);freopen("dl.out","w",stdout);
n=read();m=read();mc=read();rp(i,,n)a[i]=read();rp(i,,n)w[i]=read();rp(i,,m)mxc=max(mxc,c[i]=read());
dp();bfs();sort(zt+,zt++zt_cnt);rp(i,,m)wk(c[i]);
return ;
}

这儿是代码QAQ

洛谷P3724 大佬 [AH2017/HNOI2017] dp+bfs的更多相关文章

  1. 洛谷P3722 影魔 [AH2017/HNOI2017] 线段树+扫描线

    正解:线段树+扫描线 解题报告: 传送门! 先理解一下这道题,大概是这样儿的: 对于一个点对,如果他们的两端是这段区间的最大值和次大值,那么他们会有p1的贡献 如果他们的两端是最大值和一个非次大值,那 ...

  2. 题解 洛谷 P3726 【[AH2017/HNOI2017]抛硬币】

    可以分别枚举两人正面朝上的次数来统计答案,所求即为 \[\sum_{i=0}^{a}\sum_{j=0}^{b} \binom{a}{i} \binom{b}{j} [i>j] \] 将\(i\ ...

  3. 洛谷 P5279 - [ZJOI2019]麻将(dp 套 dp)

    洛谷题面传送门 一道 dp 套 dp 的 immortal tea 首先考虑如何判断一套牌是否已经胡牌了,考虑 \(dp\)​​​​​.我们考虑将所有牌按权值大小从大到小排成一列,那我们设 \(dp_ ...

  4. Lightning Conductor 洛谷P3515 决策单调性优化DP

    遇见的第一道决策单调性优化DP,虽然看了题解,但是新技能√,很开森. 先%FlashHu大佬,反正我是看了他的题解和精美的配图才明白的,%%%巨佬. 废话不多说,看题: 题目大意 已知一个长度为n的序 ...

  5. 【洛谷】P1052 过河【DP+路径压缩】

    P1052 过河 题目描述 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子上.由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙 ...

  6. 洛谷2344 奶牛抗议(DP+BIT+离散化)

    洛谷2344 奶牛抗议 本题地址:http://www.luogu.org/problem/show?pid=2344 题目背景 Generic Cow Protests, 2011 Feb 题目描述 ...

  7. 洛谷P1541 乌龟棋(四维DP)

    To 洛谷.1541 乌龟棋 题目背景 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物. 题目描述 乌龟棋的棋盘是一行N个格子,每个格子上一个分数(非负整数).棋盘第1格是唯一的起点,第N格是终点,游 ...

  8. 【题解】洛谷P1052 [NOIP2005TG] 过河(DP+离散化)

    题目来源:洛谷P1052 思路 一开始觉得是贪心 但是仔细一想不对 是DP 再仔细一看数据不对 有点大 如果直接存下的话 显然会炸 那么就需要考虑离散化 因为一步最大跳10格 那么我们考虑从1到10都 ...

  9. 洛谷1736(二维dp+预处理)

    洛谷1387的进阶版,但很像. 1387要求是“全为1的正方形”,取dp[i][j] = min(dp[i-1][j-1], min(dp[i-1][j], dp[i][j-1]))吧?这个有“只有对 ...

随机推荐

  1. c++ clr编译dll在c#调用时出现“试图加载不正确的格式”“找不到dll”错误的解决

    用depends发现缺了一堆API-MS-WIN什么的dll,网上查找是因为少了VC++2010,VC++2015等一系列,装好后仍然不行,原来这种错误并不是该原因导致的,也并不缺少那些dll(dep ...

  2. 同样的so,放到不同的project中,就会报错

    网上看到的帖子,笔记一下 最近在看蓝斯的一篇文章基于Platinum库的DMS实现(android) 把其中的so文件直接拷贝到了另外一个project中,jin文件也一样,唯一不同的是包名. 运行报 ...

  3. [JS] ECMAScript 6 - Variable : compare with c#

    前言 范围包括:ECMAScript 新功能以及对象. 当前的主要目的就是,JS的学习 --> ECMAScript 6 入门 let 命令 js 因为let, i的范围限制在了循环中. var ...

  4. ThinkingInJava 学习 之 0000002 操作符

    1. 更简单的打印语句 2. 使用Java操作符 3. 优先级(单目乘除位关系,逻辑三目后赋值) 4. 赋值 1. 方法调用中的别名问题 5. 算术操作符 6. 自动递增和递减 7. 关系操作符 1. ...

  5. System.getProperty()获取系统的配置信息

    原文地址:http://www.jsjtt.com/java/Javajichu/105.html 此处记录备用. 1. 通过System.getProperty()可以获取系统的配置信息,Syste ...

  6. 调用百度云Api实现从百度云盘自动下载文件

    一.注册账号 要从百度云下载文件,首先,注册一个百度云账号,现在可能都要注册手机号啦,当然,如果你已经注册过,很幸运,就可以省略掉此步骤啦. 如图登录后所示: 点击Access Key,即显示上面的图 ...

  7. Android Studio开发第三篇版本管理Git

    创建项目在前一篇讲了,这里就讲一下怎么把创建的新项目关联到远程仓库呢. 在as的菜单栏找到VCS/Import into Verson Control/Create Git Repository 弹出 ...

  8. C# Post HTTP Request

    using System; using System.Collections.Generic; using System.IO; using System.Net; using System.Secu ...

  9. EXCEL 2007施工进度横道图制作步骤及实战练习

    [知识讲解] 1.将图表中的部分图形“隐藏”起来 如果为了实现某种特殊的图表效果,需要将图表中的部分图形“隐藏”起来,除了将该系列删除外(有时候这种方法不能达到所需要的效果),还可以通过下面的方法来实 ...

  10. cordova 插件 调用iOS社交化分享(ShareSDK:微信QQ分享)

    1.github上已有的插件:https://github.com/nwpuhmz/ShareSDKPlugin 2.安装插件 cordova plugin add https://github.co ...