洛谷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 %d ",ans) ; 63 return 0 ; 64 } 65 else{ 66 printf("0 ") ; 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 ",ans) ; 75 return 0 ; 76 } 77 ans-- ; 78 } 79 printf("0 ") ; 80 } 81 return 0 ; 82 }