[USACO09OPEN]Ski Lessons

嘟嘟嘟html

 

先考慮這兩點:ios

1.若是咱們有結束時間相同的課程,且達到的能力相同,那麼咱們必定選擇開始時間最晚的。git

2.若是有能力值相同的滑雪坡,咱們必定選擇時間最短的。數組

所以先預處理兩個數組。cla[i][j]表明在 i 時刻結束,能力值達到 j 的課程中開始的最晚時間,ski[i]表明須要能力值至少爲 i 的滑雪坡中最短的時間。ide

令dp[i][j] 表示 在 i 時刻,能力值爲 j 時最多的滑雪次數,g[j]表示在當選前的時刻 i 時能力值爲 j 時最多的滑雪次數,則 g[j] = max(dp[i][k]) (k:1~j)。post

轉移的時候分一下幾種狀況:spa

1.喝可可汁:dp[i][j] = dp[i - 1][j]。code

2.若是有課恰好上完: if(cla[i - 1][j]) dp[i][j] = max(dp[i][j], g[cla[i - 1][j]]);htm

3.若是當前的時間能夠滑一次能力值至少爲 j 的滑雪坡:if(i - ski[j] >= 0) dp[i][j] = max(dp[i][j], dp[i - ski[j]][j] + 1);blog

4.最後更新g[i] = max(dp[i][j])。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<cstring>
 6 #include<cstdlib>
 7 #include<cctype>
 8 #include<vector>
 9 #include<stack>
10 #include<queue>
11 using namespace std;
12 #define enter puts("") 
13 #define space putchar(' ')
14 #define Mem(a) memset(a, 0, sizeof(a))
15 typedef long long ll;
16 typedef double db;
17 const int INF = 0x3f3f3f3f;
18 const int eps = 1e-8;
19 const int maxn = 1e4 + 5;
20 const int maxm = 105;
21 inline ll read()
22 {
23     ll ans = 0;
24     char ch = getchar(), last = ' ';
25     while(!isdigit(ch)) {last = ch; ch = getchar();}
26     while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();}
27     if(last == '-') ans = -ans;
28     return ans;
29 }
30 inline void write(ll x)
31 {
32     if(x < 0) x = -x, putchar('-');
33     if(x >= 10) write(x / 10);
34     putchar(x % 10 + '0');
35 }
36 
37 int t, s, n, Max = 1;
38 int cla[maxn][maxm], ski[maxm];
39 int dp[maxn][maxm], g[maxn];
40 
41 int main()
42 {
43     t = read(); s = read(); n = read();
44     for(int i = 1; i <= s; ++i)
45     {
46         int m = read(), l = read(), a = read();
47         cla[m + l - 1][a] = max(m, cla[m + l - 1][a]);
48         Max = max(Max, a);
49     }
50     for(int i = 1; i <= Max; ++i) ski[i] = INF; 
51     for(int i = 1; i <= n; ++i)
52     {
53         int c = read(), d = read();
54         for(int j = c; j <= Max; ++j) ski[j] = min(ski[j], d);
55     }
56     memset(dp, 128, sizeof(dp));    //要初始化一個很小的值 
57     dp[0][1] = g[0] = 0;
58     for(int i = 1; i <= t; ++i)
59     {
60         for(int j = 1; j <= Max; ++j)
61         {
62             dp[i][j] = dp[i - 1][j];
63             if(cla[i - 1][j]) dp[i][j] = max(dp[i][j], g[cla[i - 1][j]]);
64             if(i - ski[j] >= 0) dp[i][j] = max(dp[i][j], dp[i - ski[j]][j] + 1);
65             g[i] = max(g[i], dp[i][j]);
66         }
67     }
68     write(g[t]); enter;
69     return 0;
70 }
View Code
相關文章
相關標籤/搜索