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. 2016-2017 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) K Tournament Wins

    题目链接:http://codeforces.com/gym/101201 /* * @Author: lyucheng * @Date: 2017-10-22 14:38:52 * @Last Mo ...

  2. ELK 完整部署和使用 - 每天5分钟玩转 Docker 容器技术(90)

    上一节已经部署了容器化的 ELK,本节讨论如何将日志导入 ELK 并进行图形化展示. 几乎所有的软件和应用都有自己的日志文件,容器也不例外.前面我们已经知道 Docker 会将容器日志记录到 /var ...

  3. window10下的eclipse用java连接hadoop执行mapreduce任务

    一.准备工作 1.eclipse连接hadoop的插件,需要版本匹配,这有几个常用的 2 版本的插件 hadoop2x-eclipse-plugin-master 密码:feg1 2.hadoop-c ...

  4. AngularJS学习篇(十二)

    AngularJS SQL ASP.NET 中执行 SQL 获取数据 <!DOCTYPE html> <html> <head> <meta charset= ...

  5. JavaScript Function.call() 函数详解

    语法 functionObject.call( [ thisObj [, arg1 [, arg2 [, args...]]]] ) call()函数用于调用当前函数functionObject,并可 ...

  6. hdu 6231 -- K-th Number(二分+尺取)

    题目链接 Problem Description Alice are given an array A[1..N] with N numbers. Now Alice want to build an ...

  7. Docker安装Mysql数据库容器(zz)

    zz自:http://blog.csdn.net/chengxuyuanyonghu/article/details/54380032 1.下载mysql的镜像: sudo docker pull m ...

  8. Python 3.X 调用多线程C模块,并在C模块中回调python函数的示例

    由于最近在做一个C++面向Python的API封装项目,因此需要用到C扩展Python的相关知识.在此进行简要的总结. 此篇示例分为三部分.第一部分展示了如何用C在Windows中进行多线程编程:第二 ...

  9. hibernate flushMode 错误

    1 十一月 15, 2017 10:13:36 上午 org.apache.struts2.dispatcher.Dispatcher error 2 严重: Exception occurred d ...

  10. C# 控件的缩写

    1 btn Button 2 chk CheckBox 3 ckl CheckedListBox 4 cmb ComboBox 5 dtp DateTimePicker 6 lbl Label 7 l ...