洛谷P1941 飞扬的小鸟 动态规划

洛谷P1941 飞扬的小鸟
动态规划
这道题主要要注意一下飞到m以上之后高度还是 m
这个就要在判断一下
比较直接暴力的动归 是 O(N^3)
f[ i ][ j ] 到 i ,j 这个位置 所需要的最少点击次数
如果不能到,就是无限大
f[ i ][ j ] = min(f[ i-1 ][ j-up[i-1] ] +1 , f[ i-1 ][ j+down[i-1] ] )
因为可以向上飞无限次 这其实就相当于是无限背包
然后 f[ i ][ j ] 就可以从 f[ i ][ j-up[ i-1 ] ] 转移过来 枚举正向
相当于 完全背包

 1 #include <bits/stdc++.h>
 2 using namespace std ;
 3
 4 const int N = 1e4+11,M = 1e3+11,inf = 0x3f3f3f3f ;
 5 int n,m,ans,s,u,v,k ;
 6 int up[N],down[N],top[N],bot[N],f[N][M] ;
 7
 8 inline int read()
 9 {
10     int x = 0 , f = 1 ;
11     char ch = getchar() ;
12     while(ch<‘0‘||ch>‘9‘) { if(ch==‘-‘) f = -1 ; ch = getchar() ; }
13     while(ch>=‘0‘&&ch<=‘9‘) { x = x * 10+ch-48 ; ch = getchar() ; }
14     return x * f ;
15 }
16
17 int main()
18 {
19     n = read() ; m = read() ; k = read() ;
20     for(int i=0;i<n;i++)
21         up[ i ] = read() , down[ i ] = read() ;
22     for(int i=0;i<=n;i++)
23         top[ i ] = m+1 , bot[ i ] = 0 ;
24     for(int i=1;i<=k;i++)
25     {
26         s = read() ; u = read() ; v = read() ;
27         bot[ s ] = u ;
28         top[ s ] = v ;
29     }
30
31     memset(f,0x3f,sizeof(f)) ;   //  初始化 无限大
32     for(int i=1;i<=m;i++) f[ 0 ][ i ] = 0 ;
33     for(int i=1;i<=n;i++)
34     {
35         for(int j=1;j<=m;j++)
36         {
37             u = j - up[ i-1 ] ;
38             if( u>bot[i-1]&&u<top[i-1] )
39                 f[ i ][ j ] = min(f[i][j],f[i-1][u]+1) ;
40             if( u>0 )
41                 f[ i ][ j ] = min(f[i][j],f[i][u]+1) ;
42         }
43         for(int j=m;j>=m-up[i-1]&&j>=1 ; j--)       //   特殊 判断 高度 为 n 的情况
44         //for(int j=max(1,m-up[i-1]);j<=m;j++)                                       //应该无需倒序的吧
45         {
46             f[ i ][ m ] = min(f[i][m],f[i][j]+1) ;
47             if( j>bot[ i-1 ]&&j<top[ i-1 ] )
48                 f[ i ][ m ] = min(f[ i ][ m ],f[ i-1 ][ j ]+1) ;
49         }
50         for(int j=1;j<=m;j++)
51         {
52             u = j + down[ i-1 ] ;
53             if( u>bot[i-1] && u<top[i-1] )
54                 f[ i ][ j ] = min(f[ i ][ j ],f[ i-1 ][ u ]) ;
55         }
56     }
57     ans = inf ;
58     for(int i=1;i<=m;i++)
59         if(f[ n ][ i ] < ans ) ans = f[ n ][ i ] ;
60     if(ans!=inf)
61     {
62         printf("1\n%d\n",ans) ;
63         return 0 ;
64     }
65     else{
66         printf("0\n") ;
67         ans = k ;
68         for(int i=n;i>=1;i--)
69         {
70             if( top[ i ]== m+1) continue ;
71             for(int j=bot[ i ]+1;j<top[ i ];j++)
72                 if(f[ i ][ j ]<inf)
73                 {
74                     printf("%d\n",ans) ;
75                     return 0 ;
76                 }
77             ans-- ;
78         }
79         printf("0\n") ;
80     }
81     return 0 ;
82 }
时间: 2024-08-14 03:38:59

洛谷P1941 飞扬的小鸟 动态规划的相关文章

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

题目描述 Flappy Bird 是一款风靡一时的休闲手机游戏.玩家需要不断控制点击手机屏幕的频率来调节小鸟的飞行高度,让小鸟顺利通过画面右方的管道缝隙.如果小鸟一不小心撞到了水管或者掉在地上的话,便宣告失败. 为了简化问题,我们对游戏规则进行了简化和改编: 游戏界面是一个长为n ,高为 m 的二维平面,其中有k 个管道(忽略管道的宽度). 小鸟始终在游戏界面内移动.小鸟从游戏界面最左边任意整数高度位置出发,到达游戏界面最右边时,游戏完成. 小鸟每个单位时间沿横坐标方向右移的距离为1 ,竖直移动

luogu P1941 飞扬的小鸟

二次联通门 : luogu P1941 飞扬的小鸟 /* luogu P1941 飞扬的小鸟 dp 向上飞是完全背包,向下掉就是01背包 分情况讨论一下 最后合并一下 */ #include <cstdio> #include <iostream> #include <cstring> const int BUF = 123123123; char Buf[BUF], *buf = Buf; inline void read (int &now) { for (

洛谷P1133 教主的花园 动态规划

洛谷P1133 教主的花园动态规划 这里是环状的,但是我们并不用将他破环成链 只要枚举第一个点 根据第一个点选择最后一个选择什么就行了 然后我们进行DP注意如果当前是 2 的话要分情况 上一次是上升 1 还是下降 0 F1[ i ] 表示 第 i 位置的种第 1 种树所能获得的最大价值 F2[ i ][ 0 ] 表示 第 i 位置的 种第 2 种树 且上次是下降 1 #include <bits/stdc++.h> 2 #define For(i,j,k) for(int i=j;i<=

洛谷P1450 [HAOI2008]硬币购物 动态规划 + 容斥原理

洛谷P1450 [HAOI2008]硬币购物 动态规划 + 容斥原理 1.首先我们去掉限制 假设 能够取 无数次 也就是说一开始把他当做完全背包来考虑 离线DP 预处理 复杂度 4*v 用f[ i ] 表示 空间 为 i 的方案数 答案ans 其实就是所有方案 - 所有超过限制的方案 限制指的就是题目中限制 某个硬币有几枚 然后所有超过限制的方案用容斥来做 所有超过限制的方案 要减 == -1 超过限制的方案 - 2 超过限制的方案 - 3 超过限制的方案 - 4 超过限制的方案 + 1和2 超

P1941 飞扬的小鸟

题目描述 Flappy Bird 是一款风靡一时的休闲手机游戏.玩家需要不断控制点击手机屏幕的频率来调节小鸟的飞行高度,让小鸟顺利通过画面右方的管道缝隙.如果小鸟一不小心撞到了水管或者掉在地上的话,便宣告失败. 为了简化问题,我们对游戏规则进行了简化和改编: 游戏界面是一个长为n ,高为 m 的二维平面,其中有k 个管道(忽略管道的宽度). 小鸟始终在游戏界面内移动.小鸟从游戏界面最左边任意整数高度位置出发,到达游戏界面最右边时,游戏完成. 小鸟每个单位时间沿横坐标方向右移的距离为1 ,竖直移动

JZYZOJ1445 [noip2014day1-T3]飞扬的小鸟 动态规划 完全背包

http://172.20.6.3/Problem_Show.asp?id=1445 很容易看出来动态规划的本质,但是之前写的时候被卡了一下(不止一下),还是写一下题解. 直接暴力O(n*m^2)大概是70分,比较划算. 100分需要对上升下降方式找规律然后优化到O(nm): 可以看出,70分算法有很多时间浪费在没必要的上升计算上,为了减少上升计算,我们可以在预处理后把上升计算变为只有一次. 把下降的放在最后处理. 观察可以发现f[i][x]的赋值只可能来自于下面升上来的,其实本质就是一个有一点

P1941 飞扬的小鸟[dp]

题目描述 Flappy Bird是一款风靡一时的休闲手机游戏.玩家需要不断控制点击手机屏幕的频率来调节小鸟的飞行高度,让小鸟顺利通过画面右方的管道缝隙.如果小鸟一不小心撞到了水管或者掉在地上的话,便宣告失败. 为了简化问题,我们对游戏规则进行了简化和改编: 游戏界面是一个长为 nn,高为 mm 的二维平面,其中有 kk 个管道(忽略管道的宽度). 小鸟始终在游戏界面内移动.小鸟从游戏界面最左边任意整数高度位置出发,到达游戏界面最右边时,游戏完成. 小鸟每个单位时间沿横坐标方向右移的距离为 11,

【Luogu】P1941飞扬的小鸟(DP)

我发现现在没了题解我做普及提高+的题也做不了 更不要说这些提高+难度的?题 此题是一个二维DP.暴力是三重循环ijk,k枚举在i位置上的点击次数.即 for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) for(int k=1;j-k*up[i]>0;k++)    f[i][j]=min(f[i][j],f[i][k]+k); 这样的暴力能拿到80分.但是很不幸,我一开始搞错了,所以只拿了60,剩下20是TLE. 后来发现可以把水管放在外面计算.也就是

【题解】luogu P1941 飞扬的小鸟

转自  https://www.cnblogs.com/y142857/p/7134366.html 首先想到设f[i][j]表示到第i行第j列所需要的最少点击屏幕次数.转移方程为 f[ i ][ j ]=min{f[ i-1 ][ j - k*x[i-1] ] + k} (1<= k <= j/x) 上升——① f[ i ][ j ]=min{f[ i-1 ][ j + y[i-1] }  ( j + y[i-1] <= m) 下降 显然,下降可以O(1)转移,主要问题在上升的转移.