洛谷P3724 大佬 [AH2017/HNOI2017] dp+bfs
正解: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的更多相关文章
- 洛谷P3722 影魔 [AH2017/HNOI2017] 线段树+扫描线
正解:线段树+扫描线 解题报告: 传送门! 先理解一下这道题,大概是这样儿的: 对于一个点对,如果他们的两端是这段区间的最大值和次大值,那么他们会有p1的贡献 如果他们的两端是最大值和一个非次大值,那 ...
- 题解 洛谷 P3726 【[AH2017/HNOI2017]抛硬币】
可以分别枚举两人正面朝上的次数来统计答案,所求即为 \[\sum_{i=0}^{a}\sum_{j=0}^{b} \binom{a}{i} \binom{b}{j} [i>j] \] 将\(i\ ...
- 洛谷 P5279 - [ZJOI2019]麻将(dp 套 dp)
洛谷题面传送门 一道 dp 套 dp 的 immortal tea 首先考虑如何判断一套牌是否已经胡牌了,考虑 \(dp\).我们考虑将所有牌按权值大小从大到小排成一列,那我们设 \(dp_ ...
- Lightning Conductor 洛谷P3515 决策单调性优化DP
遇见的第一道决策单调性优化DP,虽然看了题解,但是新技能√,很开森. 先%FlashHu大佬,反正我是看了他的题解和精美的配图才明白的,%%%巨佬. 废话不多说,看题: 题目大意 已知一个长度为n的序 ...
- 【洛谷】P1052 过河【DP+路径压缩】
P1052 过河 题目描述 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子上.由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙 ...
- 洛谷2344 奶牛抗议(DP+BIT+离散化)
洛谷2344 奶牛抗议 本题地址:http://www.luogu.org/problem/show?pid=2344 题目背景 Generic Cow Protests, 2011 Feb 题目描述 ...
- 洛谷P1541 乌龟棋(四维DP)
To 洛谷.1541 乌龟棋 题目背景 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物. 题目描述 乌龟棋的棋盘是一行N个格子,每个格子上一个分数(非负整数).棋盘第1格是唯一的起点,第N格是终点,游 ...
- 【题解】洛谷P1052 [NOIP2005TG] 过河(DP+离散化)
题目来源:洛谷P1052 思路 一开始觉得是贪心 但是仔细一想不对 是DP 再仔细一看数据不对 有点大 如果直接存下的话 显然会炸 那么就需要考虑离散化 因为一步最大跳10格 那么我们考虑从1到10都 ...
- 洛谷1736(二维dp+预处理)
洛谷1387的进阶版,但很像. 1387要求是“全为1的正方形”,取dp[i][j] = min(dp[i-1][j-1], min(dp[i-1][j], dp[i][j-1]))吧?这个有“只有对 ...
随机推荐
- 挖坑:handoop2.6 开启kerberos(全流程学习记录)
目录: 1.涉及插件简介 2.安装步骤 3.日志错误查看 1.kerberos是什么东西 度娘指导: Kerberos 是一种网络认证协议,其设计目标是通过密钥系统为 客户机 / 服务器 应用程序提供 ...
- too many open files
压测遇到这个问题,每次都查,记录一下: 系统分配文件数太少,临时修改方案: ulimit -n 2048 永久配置: vim /etc/security/limits.conf 底部配置: # End ...
- NLog使用
NLog的配置文件,文件上面有详细的备注,注意这个配置文件一定要放在NLog.dll的文件夹里 <?xml version="1.0" encoding="utf- ...
- Java知多少(51)finally
当异常被抛出,通常方法的执行将作一个陡峭的非线性的转向.依赖于方法是怎样编码的,异常甚至可以导致方法过早返回.这在一些方法中是一个问题.例如,如果一个方法打开一个文件项并关闭,然后退出,你不希望关闭文 ...
- R语言reads.table 自动将字符串变成了逻辑值
今天遇到了一个问题,文件中有一列的值为全为F, 用read.table 读取的时候,自动将F 变成了false 对于这样的转换,可以通过 colClass 参数控制 colClass 参数指定每一列的 ...
- js实现滑动的弹性导航
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- Android Studio 编译错误
同样的代码,在eclipse里面能编译通过,导入到Android Studio里面就报错. illegal character: \65279 终于找到答案: http://bbs.csdn.net/ ...
- JQuery EasyUI DataGrid获取当前行
1.获取当前行索引 var rowIndex = $('#dg').datagrid('getRowIndex', row); 2.根据索引删除当前行 $('#dg').datagrid('delet ...
- Windows下MySQL的绿化与精简
MySQL本身就支持安装使用,本文只是对自己使用免安装版MySQL的经历记录下来,以便以后查看. 首先是获取Windows下的MySQL免安装版本,这个需要去到MySQL官网进行下载.我一般喜欢把首页 ...
- 版本控制 version control和团队协作
这些技术你可能暂时不会用到,但是一旦软件体量变大,开发人数增加,这就带来质变,需要借助一些工具或者技术才能完成这些复杂的工程. 你可以从最简单的情况思考,你可以对任何类型的文件进行版本控制,比如一个p ...