zoukankan      html  css  js  c++  java
  • 【贪心优化dp决策】bzoj1571: [Usaco2009 Open]滑雪课Ski

    还有贪心优化dp决策的操作……

    Description

    Farmer John 想要带着 Bessie 一起在科罗拉多州一起滑雪。很不幸,Bessie滑雪技术并不精湛。 Bessie了解到,在滑雪场里,每天会提供S(0<=S<=100)门滑雪课。第i节课始于M_i(1<=M_i<=10000),上的时间为L_i(1<=L_i<=10000)。上完第i节课后,Bessie的滑雪能力会变成A_i(1<=A_i<=100). 注意:这个能力是绝对的,不是能力的增长值。 Bessie买了一张地图,地图上显示了N(1 <= N <= 10,000)个可供滑雪的斜坡,从第i个斜坡的顶端滑至底部所需的时长D_i(1<=D_i<=10000),以及每个斜坡所需要的滑雪能力C_i(1<=C_i<=100),以保证滑雪的安全性。Bessie的能力必须大于等于这个等级,以使得她能够安全滑下。 Bessie可以用她的时间来滑雪,上课,或者美美地喝上一杯可可汁,但是她必须在T(1<=T<=10000)时刻离开滑雪场。这意味着她必须在T时刻之前完成最后一次滑雪。 求Bessie在实现内最多可以完成多少次滑雪。这一天开始的时候,她的滑雪能力为1.

    Input

    第1行:3个用空格隔开的整数:T, S, N。

    第2~S+1行:第i+1行用3个空格隔开的整数来描述编号为i的滑雪课:M_i,L_i,A_i。

    第S+2~S+N+1行:

    第S+i+1行用2个空格隔开的整数来描述第i个滑雪坡:C_i,D_i。

    Output

    一个整数,表示Bessie在时间限制内最多可以完成多少次滑雪。

    Sample Input

    10 1 2
    3 2 5
    4 1
    1 3

    Sample Output

    6

    HINT 

    滑第二个滑雪坡1次,然后上课,接着滑5次第一个滑雪坡。


    题目分析

    显然是道dp题,不过这里讲下贪心优化决策。

    其实这个名字可能有点太高大上了,它本质上就是通过预处理来减少复杂度。

    有动态规划$f[i][j]$表示$i$时刻能力值为$j$能够滑雪的最多次数。

    我们处理$l[i][j]$表示在$i$时刻结束的能力值为$j$的课程的最晚开始时间;$mins[i]$表示所需$1..i$能力值中用时最少的滑雪时间;$g[i]$表示$max{f[i][j]}$。

    于是对于$f[i][j]$,有三种转移方式:

    1 f[i][j] = f[i-1][j];
    2 if (l[i-1][j])
    3     f[i][j] = std::max(f[i][j], g[l[i-1][j]]);
    4 if (i >= mins[j])
    5     f[i][j] = std::max(f[i][j], f[i-mins[j]][j]+1);

    以上就是dp中的一块技巧,感觉还是非常有趣的。

     1 #include<bits/stdc++.h>
     2 const int maxn = 10035;
     3 const int maxc = 103;
     4 
     5 int t,s,n;
     6 int f[maxn][maxc],g[maxn],mins[maxc];
     7 int l[maxn][maxc];
     8 
     9 int read()
    10 {
    11     char ch = getchar();
    12     int num = 0;
    13     bool fl = 0;
    14     for (; !isdigit(ch); ch = getchar())
    15         if (ch=='-') fl = 1;
    16     for (; isdigit(ch); ch = getchar())
    17         num = (num<<1)+(num<<3)+ch-48;
    18     if (fl) num = -num;
    19     return num;
    20 }
    21 int main()
    22 {
    23     memset(mins, 0x3f3f3f3f, sizeof mins);
    24     memset(f, -0x3f3f3f3f, sizeof f);
    25     t = read(), s = read(), n = read();
    26     for (int i=1; i<=s; i++)
    27     {
    28         int x = read(), y = read(), z = read();
    29         l[x+y-1][z] = std::max(l[x+y-1][z], x);
    30     }
    31     for (int i=1; i<=n; i++)
    32     {
    33         int x = read(), y = read();
    34         for (int j=x; j<maxc; j++)
    35             mins[j] = std::min(mins[j], y);
    36     }
    37     f[0][1] = 0;
    38     for (int i=1; i<=t; i++)
    39         for (int j=1; j<maxc; j++)
    40         {
    41             f[i][j] = f[i-1][j];
    42             if (l[i-1][j])
    43                 f[i][j] = std::max(f[i][j], g[l[i-1][j]]);
    44             if (i >= mins[j])
    45                 f[i][j] = std::max(f[i][j], f[i-mins[j]][j]+1);
    46             g[i] = std::max(g[i], f[i][j]);
    47         }
    48     printf("%d
    ",g[t]);
    49     return 0;
    50 }

    END

  • 相关阅读:
    Rainmeter 雨滴桌面 主题分享
    行人检測之HOG特征(Histograms of Oriented Gradients)
    const和readonly差别
    ADB命令解析
    Java实现 蓝桥杯VIP 算法训练 接水问题
    Java实现 蓝桥杯VIP 算法训练 星际交流
    Java实现 蓝桥杯VIP 算法训练 星际交流
    Java实现 蓝桥杯VIP 算法训练 星际交流
    Java实现 蓝桥杯VIP 算法训练 星际交流
    Java实现 蓝桥杯VIP 算法训练 星际交流
  • 原文地址:https://www.cnblogs.com/antiquality/p/9263359.html
Copyright © 2011-2022 走看看