题目大意

  游戏界面是一个长为n ,高为 m 的二维平面,其中有k 个管道(忽略管道的宽度)。小鸟始终在游戏界面内移动。小鸟从游戏界面最左边任意整数高度位置出发,到达游戏界面最右边时,游戏完成。小鸟每个单位时间沿横坐标方向右移的距离为1 ,竖直移动的距离由玩家控制。如果点击屏幕,小鸟就会上升一定高度X ,每个单位时间可以点击多次,效果叠加;如果不点击屏幕,小鸟就会下降一定高度Y 。小鸟位于横坐标方向不同位置时,上升的高度X 和下降的高度Y 可能互不相同。小鸟高度等于0 或者小鸟碰到管道时,游戏失败。小鸟高度为 m 时,无法再上升。现在,请你判断是否可以完成游戏。如果可以 ,输出最少点击屏幕数;否则,输出小鸟最多可以通过多少个管道缝隙。

题解

  本题最简单的动规便是定义$f(i,j)$为第$i$个时间,高度为$j$时最少的上升步数,转移为UpdMin$f(i+1,j-Y_i),f(i,j)+1$,UpdMin$f(i+1,j+kX_i),f(i,j)+k$。然而这样时间复杂度为$O(nm^2)$,不能AC。我们想想怎么消掉那个$k$呢?我们可以这样想:对于每一个$j$,在当前时刻$t$时,我们先点屏幕一次,小鸟移到下一个时间$t'$,随后你就可以随便点屏幕让鸟在时刻$t'$中不断地上升,来更新其它高度的动规值了。这可以看作在$t'$时,把高度作为背包容量,物品体积为$X_t$,价值为$1$,动规值为$f(t',j)$的、每种物品至少选一个的完全背包了。

  注意:

  1. 先由X更新,再由Y更新,因为由X更新时,必须要满足连续地点屏幕的条件,而如果Y在前,可能会导致先不点屏幕让小鸟下降,然后再点屏幕让小鸟在$t'$时上升,不合题意。
  2. 我们只要在刷表时只由合法状态往后更新即可,以后的j如果在管道内,我们也不用管。一方面节省代码量,另一方面完全背包更新时也会需要飞到管道里中的答案。
  3. 对于点屏幕卡在屏幕上端的情况,由越界的情况往下刷即可。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; #define UpdateMin(x, y) x = min(x, y)
const int MAX_LEN = 10010, MAX_H = 1010 * 2, MAX_COL = MAX_LEN, INF = 0x3f3f3f3f;
int TotLen, TotH, TotCol;
int RiseLen[MAX_LEN], DecLen[MAX_LEN];
int High[MAX_LEN], Low[MAX_LEN];
bool ReachT;
int Ans; void DP()
{
static int F[2][MAX_COL];
memset(F[0], 0, sizeof(F[0]));
int passCnt = 0;
for (int i = 0; i < TotLen; i++)
{
bool noAns = true;
int top = min(TotH, High[i] - 1), top2 = min(TotH, High[i + 1] - 1);
for (int h = Low[i] + 1; h <= min(TotH, High[i] - 1); h++)
{
if (F[i & 1][h] < INF)
{
noAns = false;
break;
}
}
if (noAns)
{
Ans = passCnt;
return;
}
if (High[i] < INF)
passCnt++;
memset(F[i + 1 & 1], INF, sizeof(F[i + 1 & 1]));
for (int h = Low[i] + 1; h <= top; h++)
UpdateMin(F[i + 1 & 1][h + RiseLen[i]], F[i & 1][h] + 1);
for (int h = 1; h <= top2; h++)
UpdateMin(F[i + 1 & 1][h + RiseLen[i]], F[i + 1 & 1][h] + 1);
for (int h = max(Low[i] + 1, DecLen[i] + 1); h <= top; h++)
UpdateMin(F[i + 1 & 1][h - DecLen[i]], F[i & 1][h]);
if (High[i + 1] == INF)
for (int dh = 1; dh <= RiseLen[i]; dh++)
UpdateMin(F[i + 1 & 1][TotH], F[i + 1 & 1][TotH + dh]);
}
Ans = INF;
for (int h = 1; h <= TotH; h++)
UpdateMin(Ans, F[TotLen & 1][h]);
if (Ans == INF)
Ans = passCnt;
else
ReachT = true;
} int main()
{
scanf("%d%d%d", &TotLen, &TotH, &TotCol);
for (int i = 0; i < TotLen; i++)
scanf("%d%d", RiseLen + i, DecLen + i);
memset(High, INF, sizeof(High));
for (int i = 0; i < TotCol; i++)
{
int p, low, high;
scanf("%d%d%d", &p, &low, &high);
High[p] = high;
Low[p] = low;
}
DP();
printf("%d\n%d\n", ReachT, Ans);
return 0;
}

  

luogu1941 飞扬的小鸟的更多相关文章

  1. P1907飞扬的小鸟

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

  2. [codevs3729]飞扬的小鸟

    [codevs3729]飞扬的小鸟 试题描述 输入 输出 输出文件名为 bird.out. 共两行. 第一行,包含一个整数,如果可以成功完成游戏,则输出 1,否则输出 0. 第二行,包含一个整数,如果 ...

  3. Codevs 3729==洛谷P1941 飞扬的小鸟

    P1941 飞扬的小鸟 456通过 2.4K提交 题目提供者该用户不存在 标签动态规划2014NOIp提高组 难度提高+/省选- 提交该题 讨论 题解 记录   题目描述 Flappy Bird 是一 ...

  4. NOIP2014 飞扬的小鸟

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

  5. Codevs 3729 飞扬的小鸟

    飞扬的小鸟 标签 动态规划 NOIp提高组 2014 难度 提高+/省选- 题目描述 Flappy Bird 是一款风靡一时的休闲手机游戏.玩家需要不断控制点击手机屏幕的频率来调节小鸟的飞行高度,让小 ...

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

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

  7. Luogu 1941 【NOIP2014】飞扬的小鸟 (动态规划)

    Luogu 1941 [NOIP2014]飞扬的小鸟 (动态规划) Description Flappy Bird 是一款风靡一时的休闲手机游戏.玩家需要不断控制点击手机屏幕的频率来调节小鸟的飞行高度 ...

  8. UOJ #17. 【NOIP2014】飞扬的小鸟 背包DP

    #17. [NOIP2014]飞扬的小鸟 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4902  Solved: 1879 题目连接 http:// ...

  9. P1941 飞扬的小鸟(背包)

    P1941 飞扬的小鸟 细节题 上升是完全背包 下降是01背包 (数组访问越界本机怎么能过???(大雾)) #include<iostream> #include<cstdio> ...

随机推荐

  1. Luogu P1315 观光公交

    # 解题思路 一开始自己想了一个贪心,虽然贪心的主要思路是对的,但并不会统计游客用的旅行时间.所以就去题解里面看看,第一篇是最小费用最大流,会比较麻烦,所以就去看了看底下的贪心,第一篇贪心被卡掉了,看 ...

  2. UVa 11998 破碎的键盘(数组实现链表)

    题意: 输入一行字符,其中包含'[' 和 ‘]’, 意思为键盘上的home 和 end 键, 然后模拟字符在键盘上输入. 输入一行最终的结果 分析: 用数组模拟一个链表, 在链表的头尾插入字母然后输出 ...

  3. 基本dos

    文件夹的操作:   进入指定盘符:盘符名+:     dir:列出当前控制台下的所有文件以及文件夹  . cd +文件夹名称:进入指定文件夹     cd.. 返回上一级 cd \返回到当前目录的根目 ...

  4. CC3200 TI 笔记

    I2C I2C总线是由Philips公司开发的一种简单.双向二线制同步串行总线.它只需要两根线即可在连接于总线上的器件之间传送信息. I2S I2S(Inter-IC Sound)总线, 又称 集成电 ...

  5. shit IE & no table `border-collapse: collapse;`

    shit IE no table border-collapse: collapse; /* IE & shit table & border-collapse: collapse; ...

  6. noip模拟赛 轮换

    分析:模拟题,关键就是要理解题目意思.m≥3的轮换可以拆成m=2的小轮换,小轮换的话只需要交换一下就可以了. #include <cstdio> #include <cstring& ...

  7. 无法打开物理文件 "X.mdf"。操作系统错误 5:"5(拒绝访问。)"。 (Microsoft SQL Server,错误: 5120)解决

    环境 SQLServer 2008 R2 问题 附加数据库出现“无法打开物理文件 "X.mdf".操作系统错误 5:"5(拒绝访问.)". (Microsoft ...

  8. 从零开始写STL-内存部分-内存分配器allocator

    从零开始写STL-内存部分-内存分配器allocator 内存分配器是什么? 一般而言,c++的内存分配和释放是这样操作的 >>class Foo{ //...}; >>Foo ...

  9. [bzoj1510][POI2006]Kra-The Disks_暴力

    Kra-The Disks bzoj-1510 POI-2006 题目大意:题目链接. 注释:略. 想法:不难发现其实只有前缀最小值是有效的. 进而我们把盘子一个一个往里放,弄一个自底向上的指针往上蹦 ...

  10. 【.Net 学习系列】-- FileSystemWatcher 监控文件夹新生成文件,并在确认文件没有被其他程序占用后将其移动到指定文件夹

    监控文件夹测试程序: using System; using System.Collections.Generic; using System.IO; using System.Linq; using ...