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 是一款风靡一时的休闲手机游戏.玩家需要不断控制点击手机屏幕的频率来调节小鸟的飞行高度,让小鸟顺利通过画 ...
随机推荐
- dragsort拖动排序
引入文件jQuery.jquery.dragsort-0.5.2.min.js html文件: css文件: ul { margin:0px; padding:0px; margin-left:20p ...
- Spark的TorrentBroadcast:概念和原理
依据Spark 1.4.1源码 SparkContext的broadcast方法 注释 可以用SparkContext将一个变量广播到所有的executor上,使得所有executor都能获取这个变量 ...
- 【图说】Eclipse与Unity 3D协同工作
原地址:http://blog.csdn.net/h570768995/article/details/9355313 Eclipse开发过程中总会碰到很多的难题,如何利用好工具帮助我们更快捷的开发也 ...
- linux 文件比对总结
1. 过滤a.log的重复数据 #统计 cat datatest.log|sort|uniq -d |wc -l #放入b.log cat datatest.log|sort|uniq -d > ...
- 深入剖析Classloader(一)--类的主动使用与被动使用
原文地址:http://yhjhappy234.blog.163.com/blog/static/3163283220115573911607 我们知道java运行的是这样的,首先java编译器将我们 ...
- 201. Bitwise AND of Numbers Range
题目: Given a range [m, n] where 0 <= m <= n <= 2147483647, return the bitwise AND of all num ...
- POJ1850——Code(组合数学)
Code DescriptionTransmitting and memorizing information is a task that requires different coding sys ...
- JS中访问对象的属性
方式一: 对象名.属性名; 方式二: 对象名["属性名"]; ★注意:方式二中,属性名以字符串的形式出现在方括号中,这意味着通过方式二访问属性的话,可以实现“动态访问对象的 ...
- Django处理文件上传File Uploads
HttpRequest.FILES 表单上传的文件对象存储在类字典对象request.FILES中,表单格式需为multipart/form-data <form enctype="m ...
- libevent入门教程
首先给出官方文档吧: http://libevent.org ,首页有个Programming with Libevent,里面是一节一节的介绍libevent,但是感觉信息量太大了,而且还是英文的- ...