【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 是一款风靡一时的休闲手机游戏.玩家需要不断控制点击手机屏幕的频率来调节小鸟的飞行高度,让小鸟顺利通过画 ...
随机推荐
- dhtmlxScheduler日历日程控件包括天视图,周视图,月视图,年视图和日程表视图
dhtmlxScheduler 是一个基于Web的类似于Outlook的日历日程控件. 它完全由javascript/js/css编写, 提供类似于MS Outlook Calendar, Apple ...
- DotNetBar v12.9.0.0 Fully Cracked
更新信息: http://www.devcomponents.com/customeronly/releasenotes.asp?p=dnbwf&v=12.9.0.0 如果遇到破解问题可以与我 ...
- Apache Qpid Python 1.35.0 发布
Apache Qpid Python 1.35.0 发布了,Apache Qpid (Open Source AMQP Messaging) 是一个跨平台的企业通讯解决方案,实现了高级消息队列协议.提 ...
- 《JAVA学习笔记(1---13-4)》
[1]问题: 1.什么叫做面向过程? 2.什么叫做面向对象? 解答: 1: 所谓的面向过程就是我们是一个执行者,我们要开发一个项目,这个项目要求要实现很多功能,作为执行者的我们就需要 去一个一个的找这 ...
- xcode插件种类
古人云“工欲善其事必先利其器”,打造一个强大的开发环境,是立即提升自身战斗力的绝佳途径!以下是搜集的一些有力的XCode插件. 1.全能搜索家CodePilot 2.0 你要找的是文件?是文件夹? ...
- Allegro PCB SI (2)
整理一下在电研院学的si (虽然彩超的si在频率15Mhz以上后,si是失真的.昨晚遇到孔大哥也是这样说的,板级仿真,要layout过硬,然后找到合适的top test point) Allegro ...
- 从问题看本质:socket到底是什么(问答式)? .
转自:http://blog.csdn.net/yeyuangen/article/details/6799575 一.问题的引入——socket的引入是为了解决不同计算机间进程间通信的问题 1.so ...
- 虚拟机安装Linux系统图文教程
虚拟机安装Linux系统图文教程 | 浏览:523 | 更新:2014-09-16 15:31 1 2 3 4 5 6 7 分步阅读 Linux系统的安装 工具/原料 VMware 9.0 虚拟机 L ...
- Ubuntu 14.10 下sed命令详解
简介 sed 是一种在线编辑器,它一次处理一行内容.处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的 ...
- hdu 2060
ps:天了噜...WA了无数次...结果就是粗心了...先是YES和Yes的错,再后来是运算的错....想死 题意:先给出N,接下来是N个数据,给出a,b,c,分别是桌面剩下的球数,p的分数,q的分数 ...