bzoj1571 [Usaco2009 Open]滑雪课Ski
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1571
【题解】
动态规划,设f[i,j]表示第i天能力值为j最多滑几个坡
可以不滑、选个耗时最小的破滑(预处理),或者学习。
复杂度O(TS*100)
可以把那个S优化掉。
# include <stdio.h> # include <string.h> # include <iostream> # include <algorithm> // # include <bits/stdc++.h> using namespace std; typedef long long ll; typedef long double ld; typedef unsigned long long ull; const int N = 1e4 + 10, M = 1e2 + 10, inf = 1e9; # define RG register # define ST static int T, S, n; struct lecture { int m, l, a; lecture() {} lecture(int m, int l, int a) : m(m), l(l), a(a) {} }a[M]; struct pa { int c, d; pa() {} pa(int c, int d) : c(c), d(d) {} }b[N]; int f[N][M], g[N]; int p[M]; int main() { cin >> T >> S >> n; for (int i=1; i<=S; ++i) scanf("%d%d%d", &a[i].m, &a[i].l, &a[i].a); for (int i=1; i<=100; ++i) p[i] = inf; for (int i=1; i<=n; ++i) { scanf("%d%d", &b[i].c, &b[i].d); for (int j=b[i].c; j<=100; ++j) p[j] = min(p[j], b[i].d); } for (int i=1; i<=100; ++i) f[0][i] = -inf; f[0][1] = 0; for (int i=1; i<=T; ++i) { g[i] = -inf; for (int j=1; j<=100; ++j) { f[i][j] = f[i-1][j]; for (int k=1; k<=S; ++k) if(a[k].a == j && a[k].m + a[k].l == i) f[i][j] = max(f[i][j], g[a[k].m]); if(i >= p[j]) f[i][j] = max(f[i][j], f[i-p[j]][j]+1); g[i] = max(g[i], f[i][j]); } } cout << g[T]; return 0; }