看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】飞扬的小鸟的更多相关文章

  1. LOJ2500 NOIP2014 飞扬的小鸟 【背包DP】*

    LOJ2500 NOIP2014 飞扬的小鸟 LINK 题目大意就是说有n个柱子,在每一秒你可以选择不点下降高度y和点p次上升x∗p,若果当前位置加上x∗p大于上界m,就会停在m. 如果可以成功穿越所 ...

  2. [NOIP2014]飞扬的小鸟[DP]

    [NOIP2014]飞扬的小鸟 ——!x^n+y^n=z^n 题目描述: Flappy Bird 是一款风靡一时的休闲手机游戏.玩家需要不断控制点击手机屏幕的频率来调节小鸟的飞行高度,让小鸟顺利通过画 ...

  3. NOIP2014 飞扬的小鸟

    3. 飞扬的小鸟 (bird.cpp/c/pas) [问题描述] Flappy Bird 是一款风靡一时的休闲手机游戏.玩家需要不断控制点击手机屏幕的频率来调节小鸟的飞行高度,让小鸟顺利通过画面右方的 ...

  4. vijos1907[noip2014]飞扬的小鸟(完全背包)

    描述 Flappy Bird 是一款风靡一时的休闲手机游戏.玩家需要不断控制点击手机屏幕的频率来调节小鸟的飞行高度,让小鸟顺利通过画面右方的管道缝隙.如果小鸟一不小心撞到了水管或者掉在地上的话,便宣告 ...

  5. [vijos1907][NOIP2014]飞扬的小鸟

    Description 是一款风靡一时的休闲手机游戏.玩家需要不断控制点击手机屏幕的频率来调节小鸟的飞行高度,让小鸟顺利通过画面右方的管道缝隙.如果小鸟一不小心撞到了水管或者掉在地上的话,便宣告失败. ...

  6. NOIP2014飞扬的小鸟

    长为n,高为m的二维平面,其中有k个管道(忽略管道的宽度)小鸟始终在游戏界面内移动.从最左边任意高度位置出发,到达游戏界面最右边,游戏完成每个单位时间沿横坐标方向右移距离为1,竖直移动的距离由玩家控制 ...

  7. NOIP2014飞扬的小鸟[DP][WRONG]

    坑人啊朴素的dp 75分 用了完全背包才是80分,结果普遍偏小 为什么啊啊啊啊啊 等以后再写一遍吧 #include<iostream> #include<cstdio> #i ...

  8. [NOIP2014]飞扬的小鸟 D1 T3 loj2500 洛谷P1941

    分析: 这是一个DP,没什么好说的,细节很烦人. DP[i][j]表示到第i个位置,高度为j点最少的次数. 转移: 当j=m时 k属于[m-h,m]都可以向DP[i][j]转移,即dp[i][j]=m ...

  9. 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\}$ 然后考虑优化一下转移: 对于一系 ...

  10. [NOIP2014][DP]飞扬的小鸟

    [NOIP2014]飞扬的小鸟 ——!x^n+y^n=z^n 题目描述: Flappy Bird 是一款风靡一时的休闲手机游戏.玩家需要不断控制点击手机屏幕的频率来调节小鸟的飞行高度,让小鸟顺利通过画 ...

随机推荐

  1. 由于lightdm.conf 错误无法进入ubuntu 的办法

    由于自己向默认登录GNOME桌面,所以修改了lightdm,由于参数错误,结果无法启动桌面? 这是需要进入shell界面: 1.选择cancel ,如果虚拟机下无法点击cancel按钮,可以使用快捷键 ...

  2. iOS开发中的远程推送实现(最新,支持iOS9)

    我的个人项目<丁丁印记>中加入了远程推送功能,按照操作说明去做还是比较容易实现的,但是学的不够不系统,而且iOS8之后的推送和之前的版本是有所不同的,因此这篇文章希望总结一下最新的iOS推 ...

  3. 新发布GoldenGate 12c版本中的主要特性

        业界领先的实时数据集成工具GoldenGate现在可以帮助企业在传统数据库和云平台.大数据平台之间进行实时复制.新的OGG 12c支持更多的异构数据库和大数据平台,进一步提升可管理性和对混合云 ...

  4. MyQQ 前言

    从接触IOS以来也将近8个月了,学习了不少知识. 看了一系列的书籍如: <objective-c 开发入门>--语法介绍,学习一门语言是开发的基础.所以这是我大致对语法语句学习的锻炼地方, ...

  5. HYSBZ 1858 线段树 区间合并

    //Accepted 14560 KB 1532 ms //线段树 区间合并 /* 0 a b 把[a, b]区间内的所有数全变成0 1 a b 把[a, b]区间内的所有数全变成1 2 a b 把[ ...

  6. android自学笔记一

    android是什么我自闭不必多说,我们挑精华整理 一.android体系架构: android从下而上分为四层: (1)分别是linux操作系统及驱动(C语言实现) (2)本地代码(C/C++)框架 ...

  7. eclipse安装hibernate

  8. php大力力 [018节]如何联系大力力

    有事儿就注册博客园,给我发 博客园站内的 短消息呗,唉,没有人联系我呀,啦啦啦,爱我爱我,快点爱我 2015-08-26 php大力力018.如何联系大力力

  9. YII2.0上传文件

    针对于YII2.0官方手册来说,我稍微修改了一些内容具体的就是把model层里定义的uoload方法在controller方法里合并了 创建模型 namespace app\models; use y ...

  10. div居中问题

    首们需要position:absolute搜索;绝对定位. 而层的定位点,使用外补丁margin负值的方法. 负值的大小为层自身宽度高度除以二. div {      position:absolut ...