先考虑这两点:
1.如果我们有结束时间相同的课程,且达到的能力相同,那么我们一定选择开始时间最晚的。
2.如果有能力值相同的滑雪坡,我们一定选择时间最短的。
因此先预处理两个数组。cla[i][j]代表在 i 时刻结束,能力值达到 j 的课程中开始的最晚时间,ski[i]代表需要能力值至少为 i 的滑雪坡中最短的时间。
令dp[i][j] 表示 在 i 时刻,能力值为 j 时最多的滑雪次数,g[j]表示在当选前的时刻 i 时能力值为 j 时最多的滑雪次数,则 g[j] = max(dp[i][k]) (k:1~j)。
转移的时候分一下几种情况:
1.喝可可汁:dp[i][j] = dp[i - 1][j]。
2.如果有课刚好上完: if(cla[i - 1][j]) dp[i][j] = max(dp[i][j], g[cla[i - 1][j]]);
3.如果当前的时间可以滑一次能力值至少为 j 的滑雪坡:if(i - ski[j] >= 0) dp[i][j] = max(dp[i][j], dp[i - ski[j]][j] + 1);
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