NOIP2014 飞扬的小鸟
3. 飞扬的小鸟
(bird.cpp/c/pas)
【问题描述】
Flappy Bird 是一款风靡一时的休闲手机游戏。玩家需要不断控制点击手机屏幕的频率来调节小鸟的飞行高度,让小鸟顺利通过画面右方的管道缝隙。如果小鸟一不小心撞到了水管或者掉在地上的话,便宣告失败。
为了简化问题,我们对游戏规则进行了简化和改编:
- 游戏界面是一个长为n,高 为m的二维平面,其中有k个管道(忽略管道的宽度)。
- 小鸟始终在游戏界面内移动。小鸟从游戏界面最左边任意整数高度位置出发,到达游戏界面最右边时,游戏完成。
- 小鸟每个单位时间沿横坐标方向右移的距离为1,竖直移动的距离由玩家控制。如果点击屏幕,小鸟就会上升一定高度X,每个单位时间可以点击多次,效果叠加;如果不点击屏幕,小鸟就会下降一定高度Y。小鸟位于横坐标方向不同位置时,上升的高度X和下降的高度Y可能互不相同。
- 小鸟高度等于0或者小鸟碰到管道时,游 戏 失 败 。小 鸟 高 度 为m时,无法再上升。
现在,请你判断是否可以完成游戏。如果可以,输出最少点击屏幕数;否则,输出小鸟
最多可以通过多少个管道缝隙。
【输入】
输入文件名为 bird.in。
第1行有3个整数n,m,k,分别表示游戏界面的长度,高度和水管的数量,每两个整数之间用一个空格隔开;
接下来的n行,每行2个用一个空格隔开的整数X和Y,依次表示在横坐标位置0~n-1上玩家点击屏幕后,小鸟在下一位置上升的高度X,以及在这个位置上玩家不点击屏幕时,小鸟在下一位置下降的高度Y。
接下来k行,每行3个整数P,L,H,每两个整数之间用一个空格隔开。每行表示一个管道,其中P表示管道的横坐标,L表示此管道缝隙的下边沿高度为L,H表示管道缝隙上边沿的高度(输入数据保证P各不相同,但不保证按照大小顺序给出)。
【输出】
输出文件名为bird.out。
共两行。
第一行,包含一个整数,如果可以成功完成游戏,则输出1,否则输出0。
第二行,包含一个整数,如果第一行为1,则输出成功完成游戏需要最少点击屏幕数,否则,输出小鸟最多可以通过多少个管道缝隙。
【输入输出样例1】
bird.in |
bird.out |
10 10 6 3 9 9 9 1 2 1 3 1 2 1 1 2 1 2 1 1 6 2 2 1 2 7 5 1 5 6 3 5 7 5 8 8 7 9 9 1 3 |
1 6 |
【输入输出样例2】
bird.in |
bird.out |
10 10 4 1 2 3 1 2 2 1 8 1 8 3 2 2 1 2 1 2 2 1 2 1 0 2 6 7 9 9 1 4 3 8 10 |
0 3 |
【输入输出样例说明】
如下图所示,蓝色直线表示小鸟的飞行轨迹,红色直线表示管道。
【数据范围】
对于30%的数据:5≤n≤10,5≤m≤10,k=0,保证存在一组最优解使得同一单位时间最多点击屏幕3次;
对于50%的数据:5≤n≤20,5≤m≤10,保证存在一组最优解使得同一单位时间最多点击屏幕3次;
对于70%的数据:5≤n≤1000,5≤m≤100;
对于100%的数据: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。
【思路】
题目思路很简单,但是写起来总感觉不顺手。
状态转移方程:
D[i][j]=min{d[i-1][j+y[i-1], d[i-1][j-k*x[i-1]+k}
这里的k容易联想到完全背包的无限物品,类似的,不用去枚举k,改成d[i][j-x[i]]+1,它的意思其实就是累计。修改之后还需要注意由y划分子问题应该放在x之后,否则会造成决策叠加的效果。
J==m的特殊情况:注意到题目中说“小 鸟 高 度 为m时,无法再上升。”特殊处理:也是用累计的方法,d[i][j]=min(d[i][j],d[i][pos]+1) pos from [j-x[i-1],m] 由点成为了线段。
Fly失败:用一个flag,只要d[i][]全都为INF则问题不能求解,相应输出结束。
【代码】
#include<iostream>
#define FOR(a,b,c) for(int a=(b);a<(c);a++)
using namespace std; const int INF=<<;
const int maxn = + , maxm = +;
int n,m,K;
int d[maxn][maxm];
int x[maxn],y[maxn],up[maxn],down[maxn]; int main() {
ios::sync_with_stdio(false); cin>>n>>m>>K;
FOR(i,,n) {
cin>>x[i]>>y[i];
up[i]=m+; down[i]=; //down=0 up=m+1
} up[n]=m+; down[n]=; FOR(i,,K) {
int p; cin>>p;
cin>>down[p]>>up[p];
}
FOR(i,,n+) FOR(j,,m+) d[i][j]=INF;
d[][]=INF;//d声明在全局变量自动清0 FOR(i,,n+) //i从1开始 到n结束
{
bool flag=true;
FOR(j,down[i]+,up[i]) { //这里写错过==
if(j-x[i-]>down[i-]) {
d[i][j]=min(d[i][j],d[i][j-x[i-]]+);
d[i][j]=min(d[i][j],d[i-][j-x[i-]]+);
}
if(j==m) FOR(pos,j-x[i-],j+) { //特殊情况特殊判断//注意不要写在上一个if里
d[i][j]=min(d[i][j],d[i][pos]+);
d[i][j]=min(d[i][j],d[i-][pos]+);
}
if(d[i][j]<INF) flag=false;
}
//求完关于x之后才能求y 否则x中的决策d[i][j-x[i]]可能会转移到y中求过的状态 造成既下降又上升的情况
FOR(j,down[i]+,up[i]) if(j+y[i-]<up[i-]) {
d[i][j]=min(d[i][j],d[i-][j+y[i-]]);
if(d[i][j]<INF) flag=false;
} if(flag) { //如果本i不能通过那么output退出
int sum=;
FOR(k,,i)
if(up[k]!=m+ || down[k]!=) sum++; //如果是管道 //||而非&&
cout<<<<"\n"<<sum;
return ;
}
} int mini=INF;
FOR(j,,m+) mini=min(mini,d[n][j]); //最右边为n
cout<<<<"\n"<<mini;
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 是一款风靡一时的休闲手机游戏.玩家需要不断控制点击手机屏幕的频率来调节小鸟的飞行高度,让小鸟顺利通过画 ...
- 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 是一款风靡一时的休闲手机游戏.玩家需要不断控制点击手机屏幕的频率来调节小鸟的飞行高度,让小鸟顺利通过画 ...
随机推荐
- Android EditText边框颜色的selector 使用focus标记当前填写的框
案例:当选中一个EditText时,将其边框变为蓝色,其他未被选中的EditText则为灰色. 主界面: <?xml version="1.0" encoding=" ...
- TCP协议可靠性数据传输实现原理分析
http://blog.csdn.net/chexlong/article/details/6123087 TCP 协议是一种面向连接的,为不同主机进程间提供可靠数据传输的协议.TCP 协议假定其所使 ...
- Source Insight的应用技巧、宏功能
目录 1 简介... 5 2 搭建我们的SI环境... 5 2.1 搭建步骤... 5 2.2 说明... 6 3 应用技巧... 6 3.1 初级应用技巧... 6 3.1.1 解决字体不等宽与对齐 ...
- WPF之给使用了模板的MenuItem添加快捷操作
说在前面: WPF中给按钮或者是具备Command等元素实现快捷键其实是非常简单的,例子如下: <Button Content="_Test" Click="But ...
- C#+SQL数据库备份和还原
使用前要导入SQLDMO.dll(在com组件中导入Microsoft SQLDMO Object Library即可) /// /// DbOper类,主要应用SQLDMO实现对Microsoft ...
- 25.allegro中模块复用[原创]
一,Module reuse 1,打开原理图 ------------------- --------------------- ctrl+i过滤器 直选part ctrl+e 查看属性 查看: 是否 ...
- delphi使用 第三方控件
第三方控件安装时必须把所有的pas,dcu,dpk,res等文件复制到你的Lib目录下 然后通过dpk进行安装 安装后会多出来新的控件面板,新控件就在那里了 当然也有一些控件会安装到原有的面板上 比如 ...
- JADE平台入门
相关介绍: JADE(Java Agent Development Framework,Java智能体开发框架) 用途: Java智能体开发框架 开发者: TILAB 主要功能: AMS.DF.ACC ...
- HTML5学习(四)---Canvas绘图
参考教程地址:http://www.w3school.com.cn/html5/html_5_canvas.asp canvas 元素用于在网页上绘制图形. 什么是 Canvas? HTML5 的 c ...
- C++中const小结
1.const修饰普通变量(非指针变量)const修饰变量,一般有两种写法:const TYPE value;TYPE const value;对于一个非指针的类型TYPE,这两种写法在本质上是一样的 ...