https://www.luogu.org/problem/show?pid=1941

从某一点开始飞直到飞出地图最少点击屏幕的次数,显然只和该点的坐标唯一相关,没有后效性,考虑用DP解。
令f(i,j)为从点(i,j)飞出地图最少点击次数。得状态转移方程:f(i,j)=min{f(i-1,j-k*x[i-1]+k), f(i-1,j+y[i-1])}
其实就是完全背包和01背包的结合。时间复杂度为O(nm2)。
初始状态:f(0,i)=0 (1<=i<=m),其他的都是∞。还得注意∞不能太大。

特别的,当位置i没有水管时。f(i,m)=min{…, f(i-1,k)+1, f(i,k)+1}  (m-x[i-1]+1<=k<=m)
这是因为高度在[m-x[i-1]+1, m]的鸟再跳一下就登顶了。

求解的时候顺便记录ans[i]=min{f(i,j)},如果出现了ans[i]=∞,说明到这里鸟就飞不动了,输出结果后直接结束。如果整个求解的过程都没有出现这种情况,说明鸟可以飞出去,ans[n]就是最终解。

可以把第一维滚成2,优化空间复杂度。求解时用dp[i%2][j]代替dp[i][j],dp[(i-1)%2][j]代替dp[i-1][j]。不滚好像会MLE。

既然是01背包和完全背包的结合,可以考虑套上完全背包的优化算法:把k拆开,得f(i,j)=min{f(i-1,j-x[i-1])+1, f(i,j-x[i-1])+1, f(i-1,j+y[i-1])},时间复杂度降为O(nm)。这时需要注意第二维先计算所有往上飞的状态,再计算往下掉的状态。否则f(i,j-x[i-1])+1有可能会变成一个时间内既往下掉又往上飞这种神奇的解。

这题细节超多,我WA了无数次才过。随便举个例子:开始的时候我只计算两根水管中间的高度的状态,75分。然后改成计算所有高度的状态,完了之后再把有水管的位置赋值∞,神奇的A了。为什么会这样呢?

如图↓↓↓。如果鸟在这个位置跳一下会撞水管,但是跳两下不会,也需要计算好跳一下撞水管的解。因为计算跳两下的解时候,需要用到跳一下的解。

#include <iostream>
#include <algorithm>
#define maxn 10005
using namespace std;
const int inf = 0x3f3f3f3f;
int n, m, k;
int x[maxn], y[maxn], l[maxn], h[maxn];
bool exist[maxn];
int dp[][maxn];
int main()
{
ios::sync_with_stdio(false);
cin >> n >> m >> k;
for (int i = ; i < n; i++)
cin >> x[i] >> y[i];
for (int i = ; i <= n; i++)
h[i] = m + ;
int a;
for (int i = ; i < k; i++)
{
cin >> a;
exist[a] = true;
cin >> l[a] >> h[a];
} dp[][] = inf;
int cnt = , ans;
for (int i = ; i <= n; i++)
{
for (int j = ; j <= m; j++)
dp[i & ][j] = inf; for (int j = x[i - ] + ; j <= h[i] - ; j++) // 往上飞,注意有水管的位置也要计算
{
dp[i & ][j] = min(dp[i & ][j], dp[(i - ) & ][j - x[i - ]] + );
dp[i & ][j] = min(dp[i & ][j], dp[i & ][j - x[i - ]] + );
}
for (int j = m - x[i - ] + ; j <= h[i] - ; j++) // 特殊处理高度m
{
dp[i & ][m] = min(dp[i & ][m], dp[i & ][j] + );
dp[i & ][m] = min(dp[i & ][m], dp[(i - ) & ][j] + );
}
for (int j = l[i] + ; j <= min(m - y[i - ], h[i] - ); j++) // 往下掉
{
dp[i & ][j] = min(dp[i & ][j], dp[(i - ) & ][j + y[i - ]]);
} if (exist[i]) // 去掉水管位置的不合法解
{
for (int j = ; j <= l[i]; j++)
dp[i & ][j] = inf;
for (int j = h[i]; j <= m; j++)
dp[i & ][j] = inf;
} ans = inf;
for (int j = ; j <= m; j++)
ans = min(ans, dp[i & ][j]);
if (ans == inf)
{
cout << << endl
<< cnt << endl;
return ;
}
else if (exist[i])
cnt++;
}
cout << << endl
<< ans << endl;
return ;
}

【NOIP2014提高组】飞扬的小鸟的更多相关文章

  1. 垃圾陷阱 && [NOIP2014 提高组] 飞扬的小鸟

    #include<bits/stdc++.h> using namespace std; int d,n,dp[1010]; struct node{int t,f,h;} a[1010] ...

  2. [DP]Luogu 2014NOIP提高组 飞扬的小鸟题解

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

  3. 刷题总结——飞扬的小鸟(NOIP2014提高组)

    题目: 题目背景 NOIP2014 提高组 Day1 试题. 题目描述 Flappy Bird 是一款风靡一时的休闲手机游戏.玩家需要不断控制点击手机屏幕的频率来调节小鸟的飞行高度,让小鸟顺利通过画面 ...

  4. [NOIP2014] 提高组 洛谷P2038 无线网络发射器选址

    题目描述 随着智能手机的日益普及,人们对无线网的需求日益增大.某城市决定对城市内的公共场所覆盖无线网. 假设该城市的布局为由严格平行的129 条东西向街道和129 条南北向街道所形成的网格状,并且相邻 ...

  5. NOIP2014提高组 酱油记

    NOIP考到哪里我就写到哪里好了. 2014/10/12 初赛 下午两点半开始考,我两点就到了.然后看到了QYL,NYZ,CZR等大神,先Orz了再说. 考试开始前,发现考场竟然没几个我认识的,不是按 ...

  6. NOIP2014提高组 DAY1 -SilverN

    T1  生活大爆炸版石头剪刀布 题目描述 石头剪刀布是常见的猜拳游戏:石头胜剪刀,剪刀胜布,布胜石头.如果两个人出拳一样,则不分胜负.在<生活大爆炸>第二季第8 集中出现了一种石头剪刀布的 ...

  7. noip2014 提高组

    T1 生活大爆炸版 石头剪刀布 题目传送门 就是道模拟题咯 #include<algorithm> #include<cstdio> #include<cstring&g ...

  8. NOIP2014提高组 题解报告

    D1 T1 无线网路发射器选址 题目大意:找一个矩形,使其覆盖的目标点最大. 题目过水,直接暴力搞过去,代码就不贴了. 但我TM居然有个地方SB了,调了半天才发现输入有问题: scanf(" ...

  9. 【学术篇】luogu1351 [NOIP2014提高组] 联合权值

    一道提高组的题..... 传送门:题目在这里.... 现在都懒得更自己的blog了,怕是太颓废了_ (:з」∠) _ 好久没做题了,手都生了.(好吧其实是做题方面手太生了) 这题我都不想讲了,把代码一 ...

  10. [NOIP2014] 提高组 洛谷P1941 飞扬的小鸟

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

随机推荐

  1. django 实现登录时候输入密码错误5次锁定用户十分钟

    在学习django的时候,想要实现登录失败后,进行用户锁定,切记录锁定时间,在网上找了很多资料,但是都感觉不是那么靠谱, 于是乎,我开始了我的设计,其实我一开始想要借助redis呢,但是想要先开发一个 ...

  2. Best Coder #86 1002 NanoApe Loves Sequence

    NanoApe Loves Sequence Accepts: 531 Submissions: 2481 Time Limit: 2000/1000 MS (Java/Others) Memory ...

  3. Surround the Trees(凸包)

    Surround the Trees Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  4. css之定位(position)

    1.什么是定位: css中的position属性,position有四个值:absolute/relative/fixed/static(绝对/相对/固定/静态(默认))通过定位属性可以设置一些不规则 ...

  5. http 状态

    用户如果向您的服务器发出了某项请求要求显示您网站上的某个网页(例如,当用户通过浏览器访问您的网页或在 Googlebot 抓取该网页时),那么,您的服务器会返回 HTTP 状态代码以响应该请求.此状态 ...

  6. C语言实现二叉树的基本操作

    二叉树是一种非常重要的数据结构.本文总结了二叉树的常见操作:二叉树的构建,查找,删除,二叉树的遍历(包括前序遍历.中序遍历.后序遍历.层次遍历),二叉搜索树的构造等. 1. 二叉树的构建 二叉树的基本 ...

  7. 配置好postfix邮件服务器之后就可以使用它来发送邮件了

    下面是一段摘自W3school关于php mail函数的栗子,经过测试发现两个问题. <?php $to = "somebody@example.com, somebodyelse@e ...

  8. params修饰符

    http://msdn.microsoft.com/zh-cn/library/w5zay9db.aspx params 关键字可以指定采用数目可变的参数的方法参数. 可以发送参数声明中所指定类型的逗 ...

  9. 直接调用VS.net2005中的配置界面

    以前做Winform程序,居然专门做一个界面来配置连接字符串.今天无意中发现:竟然可以直接调用VS.net2005中的配置界面来处理. 使用方法也非常简单: 引用C:\Program Files\Mi ...

  10. Android基础Activity篇之什么是Activity?

    Activity是Android的四大组件之一,也是平时我们用到最多的一个组件,可以用来显示View.官方的说法是Activity一个应用程序的组件,它提供一个屏幕来与用户交互,以便做一些诸如打电话. ...