【NOIP2014】飞扬的小鸟
看syq的代码写出来的,chty_orz
原题:
Flappy Bird 是一款风靡一时的休闲手机游戏。玩家需要不断控制点击手机屏幕的频率来调节小鸟的飞行高度,让小鸟顺利通过画面右方的管道缝隙。如果小鸟一不小心撞到了水管或者掉在地上的话,便宣告失败。
为了简化问题,我们对游戏规则进行了简化和改编:
1. 游戏界面是一个长为 n,高为 m 的二维平面,其中有k 个管道(忽略管道的宽度)。
2. 小鸟始终在游戏界面内移动。小鸟从游戏界面最左边任意整数高度位置出发,到达游戏界面最右边时,游戏完成。
3. 小鸟每个单位时间沿横坐标方向右移的距离为 1,竖直移动的距离由玩家控制。如果点击屏幕,小鸟就会上升一定高度 X,每个单位时间可以点击多次,效果叠加;如果不点击屏幕,小鸟就会下降一定高度 Y。小鸟位于横坐标方向不同位置时,上升的高度 X 和下降的高度 Y 可能互不相同。
4. 小鸟高度等于 0 或者小鸟碰到管道时,游戏失败。小鸟高度为 m 时,无法再上升。
现在,请你判断是否可以完成游戏。如果可以,输出最少点击屏幕数;否则,输出小鸟最多可以通过多少个管道缝隙。
5≤n≤10000,5≤m≤1000,0≤k<n,0<X<m,0<Y<m,0<P<n,0≤L<H≤m,L+1<H。
这个DP呢代码非常简单,如果看题解的话很容易就写出来了,主要就是状态转移方程要变一下
裸的方程很好推,f[i][j]=min(f[i][j],f[i-1][j-k*x[i]]+k),这样能拿60-70,还是挺实惠的
如果想A掉的话,就要优化这个方程,这个方程搞了三重循环,要把k的内个优化掉
然后有酱紫两个方程f[i][j]=min(f[i][j],f[i-1][j-k*x[i]]+k),f[i][j-x]=min(f[i][j-x],f[i-1][j-x-(k-1)*x]+k-1)
这两个方程就和求等比数列通项公式内样乘上个系数所有的项都往右移了一格,然后减一下,就变成了
f[i][j]=f[i][j-x]+1,所以f[i][j]=min(f[i-1][j-x],f[i][j-x])+1,然后f[i][j]就能O(1)算了
用这个方程推过去就好,要注意处理撞墙和撞顶的情况
最后扫一遍即可
有时候DP复杂度比较高的时候,就可以考虑用一些奇奇怪怪的方式把一些东西约掉,或许我要去学一下斜率优化?
这题我是参考chty的代码写的,他的代码中有这么一段:

看到这段的时候我大概是这个样子:

所有的f一开始都全设成INF了,min(f[i][j])怎么搞???
然后跟踪了一下才发现原来f[0]中只有f[0][0]被设成INF了,剩下的还是0,因为鸟可以从任意位置开始飞,但是不能从零开始
这题我之前是看过一遍的,再想做的时候就凭上次的记忆直接开始做,没好好看题,甚至题意都曲解了,所以不管什么时候开始做某道题,就算之前看过了,也一定要认真把问题扫一遍
同时也显示出来我考虑不严谨,思维没有覆盖到f[0]
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int read(){int z=,mark=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')mark=-; ch=getchar();}
while(ch>=''&&ch<=''){z=(z<<)+(z<<)+ch-''; ch=getchar();}
return z*mark;
}
int oo=;
int n,m,p,up[],down[],ding[],di[];
int f[][];
int main(){//freopen("ddd.in","r",stdin);
memset(ding,,sizeof(ding)),memset(di,,sizeof(di));
memset(f,,sizeof(f));
cin>>n>>m>>p;
for(int i=;i<=n;i++){ up[i-]=read(),down[i-]=read(); di[i]=,ding[i]=m+;}//顶部也有可能是m,注意是从0到n
int _x;
for(int i=;i<=p;i++){ _x=read(); di[_x]=read(),ding[_x]=read();}
f[][]=oo; for(int i=;i<=m;i++)f[][i]=;//可以从任意高度开始,但不能是0
for(int i=;i<=n;i++){
for(int j=up[i-];j<=m;j++){
f[i][j]=min(f[i][j],f[i][j-up[i-]]+);
f[i][j]=min(f[i][j],f[i-][j-up[i-]]+);
}
for(int j=m-up[i-];j<=m;j++){
f[i][m]=min(f[i][m],f[i-][j]+);
f[i][m]=min(f[i][m],f[i][j]+);
}
for(int j=di[i]+;j<=ding[i]-;j++)if(j+down[i-]<=m)
f[i][j]=min(f[i][j],f[i-][j+down[i-]]);
for(int j=;j<=di[i];j++) f[i][j]=oo;
for(int j=ding[i];j<=m;j++) f[i][j]=oo;
}
int bu=p,ans=oo;
for(int i=n;i>=;i--){
for(int j=di[i]+;j<=ding[i]-;j++)
ans=min(f[i][j],ans);
if(ans!=oo) break;
if(ding[i]<=m) bu--;
}
if(bu==p) cout<<<<endl<<ans<<endl;
else cout<<<<endl<<bu<<endl;
return ;
}
【NOIP2014】飞扬的小鸟的更多相关文章
- LOJ2500 NOIP2014 飞扬的小鸟 【背包DP】*
LOJ2500 NOIP2014 飞扬的小鸟 LINK 题目大意就是说有n个柱子,在每一秒你可以选择不点下降高度y和点p次上升x∗p,若果当前位置加上x∗p大于上界m,就会停在m. 如果可以成功穿越所 ...
- [NOIP2014]飞扬的小鸟[DP]
[NOIP2014]飞扬的小鸟 ——!x^n+y^n=z^n 题目描述: Flappy Bird 是一款风靡一时的休闲手机游戏.玩家需要不断控制点击手机屏幕的频率来调节小鸟的飞行高度,让小鸟顺利通过画 ...
- NOIP2014 飞扬的小鸟
3. 飞扬的小鸟 (bird.cpp/c/pas) [问题描述] Flappy Bird 是一款风靡一时的休闲手机游戏.玩家需要不断控制点击手机屏幕的频率来调节小鸟的飞行高度,让小鸟顺利通过画面右方的 ...
- vijos1907[noip2014]飞扬的小鸟(完全背包)
描述 Flappy Bird 是一款风靡一时的休闲手机游戏.玩家需要不断控制点击手机屏幕的频率来调节小鸟的飞行高度,让小鸟顺利通过画面右方的管道缝隙.如果小鸟一不小心撞到了水管或者掉在地上的话,便宣告 ...
- [vijos1907][NOIP2014]飞扬的小鸟
Description 是一款风靡一时的休闲手机游戏.玩家需要不断控制点击手机屏幕的频率来调节小鸟的飞行高度,让小鸟顺利通过画面右方的管道缝隙.如果小鸟一不小心撞到了水管或者掉在地上的话,便宣告失败. ...
- NOIP2014飞扬的小鸟
长为n,高为m的二维平面,其中有k个管道(忽略管道的宽度)小鸟始终在游戏界面内移动.从最左边任意高度位置出发,到达游戏界面最右边,游戏完成每个单位时间沿横坐标方向右移距离为1,竖直移动的距离由玩家控制 ...
- NOIP2014飞扬的小鸟[DP][WRONG]
坑人啊朴素的dp 75分 用了完全背包才是80分,结果普遍偏小 为什么啊啊啊啊啊 等以后再写一遍吧 #include<iostream> #include<cstdio> #i ...
- [NOIP2014]飞扬的小鸟 D1 T3 loj2500 洛谷P1941
分析: 这是一个DP,没什么好说的,细节很烦人. DP[i][j]表示到第i个位置,高度为j点最少的次数. 转移: 当j=m时 k属于[m-h,m]都可以向DP[i][j]转移,即dp[i][j]=m ...
- luogu1941 [NOIp2014]飞扬的小鸟 (dp)
设f[i][j]为到达(i,j)这个位置的最小操作数 就有$f[i][j]=min\{f[i-1][j+Y[i-1]],f[i-1][j-X[i-1]*k]+k\}$ 然后考虑优化一下转移: 对于一系 ...
- [NOIP2014][DP]飞扬的小鸟
[NOIP2014]飞扬的小鸟 ——!x^n+y^n=z^n 题目描述: Flappy Bird 是一款风靡一时的休闲手机游戏.玩家需要不断控制点击手机屏幕的频率来调节小鸟的飞行高度,让小鸟顺利通过画 ...
随机推荐
- 入门-Arcmap网络分析示例
1.打开arcmap并加载网络数据西安市地图(city.mdb): 它包含的图层有: 2.显示网络中的流向: 3.在设施网络分析工具条上,点选旗标和障碍工具板下拉箭头,将旗标放在city_net_ju ...
- 【iOS开发】企业版证书($299)In-House方式发布指南 (转)
一.明确几个概念 1.企业版IDP:即iOS Development Enterprise Program.注意是$299/Year那种,并不是$99/Year的那种. 2.In House:是只企业 ...
- hdu 1950 最长上升子序列
//Accepted 3540 KB 62 ms //dp 最长上升子序列 #include <cstdio> #include <cstring> #include < ...
- PAT 05-树6 Path in a Heap
这次的作业完全是依葫芦画瓢,参照云课堂<数据结构>(http://mooc.study.163.com/learn/ZJU-1000033001#/learn/content)中何钦铭老师 ...
- msf生成shellcode
msfpayload windows/exec CMD = calc.exe EXITFUNC=thread C 在kali Linux2.0新版中msfpayload命令已删除,功能已集成到msfv ...
- Oracle的DDL、DML、DCL
DDL (Data Definition Language 数据定义语言) create table 创建表 alter table 修改表 drop table 删除表 truncate table ...
- redis简介以及与memcached比较
一.redis (1)简介: Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API.是noSql数据库的一种. re ...
- How Android Draws Views
https://developer.android.com/guide/topics/ui/how-android-draws.html
- paramiko堡垒机、线程及锁
1.使用paramiko实现ssh连接和scp拷贝 开发堡垒机之前,先来学习Python的paramiko模块,该模块机遇SSH用于连接远程服务器并执行相关操作 1.1 SSHClient 用于连接远 ...
- STL源码分析----神奇的 list 的 sort 算法实现
STL中有一个std::sort算法,但它是不支持std::list的,因为list不提供RandomIterator的支持,但list自己提供了sort算法,把list的元素按从小到大的方式来排序, ...