首页 > 代码库 > [luoguP1941] 飞扬的小鸟(DP)
[luoguP1941] 飞扬的小鸟(DP)
传送门
动归,用f[i][j]表示到达第I列高度为j时最少需要飞的次数,容易想到最裸的转移:
f[i][j]=min(min(f[i-1][j-up[i-1]*k]+k),f[i-1][j+down[i-1]])
但是会超时
考虑怎么优化k的循环,发现k可以从k-1转移过来,从图上来理解就是比如k=2时,相当于可以先从i-1列飞一次飞到i列的j-up[i-1]位置,然后再往上跳一次跳到i的j位置,也就是f[i][j]可以从f[i]
[j-up[i-1]]+1转移来,这里需要注意几个地方
1.由于f[i][j-up[i-1]]相当于是中转的位置,所以无论那个位置是不是管道都要做
2.要保证f[i][j-up[i-1]]可以充当中转,所以必须先做一次只飞不掉的,再做一次掉下来的,否则会出现f[i][j-up[i-1]]位置可能是从i-1列掉下来得到的,此时不能充当中转
3.要特殊处理高度为m的情况(看题目)
——代码
1 #include <cstdio> 2 #include <iostream> 3 4 const int INF = 19260817, N = 10001, M = 1001; 5 int n, m, k, b, ans = INF, sum; 6 int x[N], y[N], l[N], h[N], f[2][M]; 7 8 inline int read() 9 {10 int x = 0, f = 1;11 char ch = getchar();12 for(; !isdigit(ch); ch = getchar()) if(ch == ‘-‘) f = -1;13 for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - ‘0‘;14 return x * f;15 }16 17 inline int min(int x, int y)18 {19 return x < y ? x : y;20 }21 22 int main()23 {24 int i, j, p;25 n = read();26 m = read();27 k = read();28 for(i = 0; i < n; i++)29 {30 x[i] = read();31 y[i] = read();32 }33 for(i = 1; i <= k; i++)34 {35 p = read();36 l[p] = read();37 h[p] = read();38 }39 for(i = 1; i <= n; i++)40 {41 for(j = 1; j <= m; j++) f[i & 1][j] = INF;42 for(j = x[i - 1] + 1; j <= m; j++)43 f[i & 1][j] = min(f[i & 1][j], f[i & 1 ^ 1][j - x[i - 1]] + 1),44 f[i & 1][j] = min(f[i & 1][j], f[i & 1][j - x[i - 1]] + 1);45 for(j = m - x[i - 1]; j <= m; j++)46 f[i & 1][m] = min(f[i & 1][m], f[i & 1 ^ 1][j] + 1),47 f[i & 1][m] = min(f[i & 1][m], f[i & 1][j] + 1); 48 for(j = 1; j <= m - y[i - 1]; j++) f[i & 1][j] = min(f[i & 1][j], f[i & 1 ^ 1][j + y[i - 1]]);49 if(l[i]) for(j = 1; j <= l[i]; j++) f[i & 1][j] = INF;50 if(h[i]) for(j = h[i]; j <= m; j++) f[i & 1][j] = INF;51 if(l[i] || h[i])52 {53 b = 0;54 for(j = l[i] + 1; j < h[i]; j++)55 if(f[i & 1][j] < INF)56 {57 b = 1;58 break;59 }60 if(b) sum++;61 else break;62 }63 }64 if(i == n + 1)65 {66 for(j = 1; j <= m; j++) ans = min(ans, f[n & 1][j]);67 printf("1\n%d\n", ans);68 }69 else printf("0\n%d\n", sum);70 return 0;71 }
[luoguP1941] 飞扬的小鸟(DP)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。