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. Javascript中的Trait与代码重用

    Javascript中的Trait与代码重用 来源 http://www.ituring.com.cn/article/64103 我们知道,OOP中最普遍的代码重用方式是通过继承,但是,继承有一些缺 ...

  2. Lua与javascript的差异

    Lua与javascript的差异 2010-03-08 Lua模拟器js方案 1.语法级模拟 lua与js语言差异 1.1注释 js 为//,lua为--. 1.2变量 js利用var来声明全局变量 ...

  3. 【DG】利用闪回数据库(flashback)修复Failover后的DG环境

    利用闪回数据库(flashback)修复Failover后的DG环境 1.1  BLOG文档结构图 1.2  前言部分 1.2.1  导读和注意事项 各位技术爱好者,看完本文后,你可以掌握如下的技能, ...

  4. Android 开发笔记___DatePicker__日期选择器

    虽然EditText提供了inputTtype="date",但用户往往不太喜欢自己输入时间. Android为这个提供了DatePicker,但有很多缺点,不是弹窗模式,而是直接 ...

  5. bash脚本条件测试总结

    一.if语句的结构 分为以下三种:单分支.双分支.多分支 单分支if语句 if CONDITION is True: then 分支 fi 双分支if语句 if CONDITION is True: ...

  6. php缓存模块apc可能导致php-fpm终止

    如果你的网站出现502错误.同时你网站中又使用了apc模块来做缓存处理.那么这篇文章兴许能帮到你. 首先,查看了php-fpm 的进程数. 发现php-fpm的进程数已经到达了php-fpm.conf ...

  7. Three.js 保存camera(视角)设置到数据库,包括场景的缩放、旋转、移动等

    最近在做的项目中遇到需要保存当前的3d管道视角设置的问题,用户希望在对3d场景内的管道进行了缩放.旋转.移动之后可以将场景当前的视角状态保存在数据库中,并在下次加载时读取. 经过不断的尝试和研究,在同 ...

  8. maven构建SSM--pox.mxl

    最近在做项目,把maven构建SSM的pom.xml文件内容小结一下: 在console中输入如下内容,使用maven创建java web项目: mvn archetype:generate -Dgr ...

  9. JDK8 指南(译)

    翻译自 java8-tutorial 新特性 Default Methods for Interfaces(接口的默认方法) Java 8 使我们能够通过使用 default 关键字将非抽象方法实现添 ...

  10. C#线程调用带参数的方法

    在 .NET Framework 2.0 版中,要实现线程调用带参数的方法有两种办法.第一种:使用ParameterizedThreadStart.调用 System.Threading.Thread ...