首页 > 代码库 > bzoj1571 [Usaco2009 Open]滑雪课Ski

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;
}
View Code

 

bzoj1571 [Usaco2009 Open]滑雪课Ski