• [USACO09OPEN]Ski Lessons


    嘟嘟嘟

    先考虑这两点:

    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
  • 相关阅读:
    java代码确认出ip和主机名
    java代码getHostAddress .getHostName()的练习
    java代码用户界面网格布局GridLayout.划分为格子区域
    java图形用户界面BorderLayout布局。冲突
    java图形用户界面添加背景颜色不成功的解决方案
    java图形用户界面练习。j2se
    java代码Calendar类
    java图形用户界面添加图片的代码
    java图形用户界面边界布局管理器
    P1120 小木棍 [数据加强版]
  • 原文地址:https://www.cnblogs.com/mrclr/p/9559281.html
Copyright © 2020-2023  润新知