• 【LSGDOJ 1850】滑雪课程


    题目描述

    贝西去科罗拉多州去滑雪,不过还她不太会玩,只是个能力为 1 的渣渣。贝西从 0 时刻进入滑雪场,一到 T 时刻就必须离开。滑雪场里有 N 条斜坡,第 i 条斜坡滑行一次需要 D i 分钟,要求游客的能力达到 C i 或以上时才能进入。贝西决心参加一些滑雪课程以提高自己的素质,这样可以在有限的时间内多滑几次坡。

    滑雪场提供了 S 门课程。第 i 门课的开始时刻为 M i ,持续 L i 分钟,如果想参加课程,就不能迟到或早退。上完课之后,贝西的滑雪能力将变成 A i 。注意,不是能力增加 A i ,而是变成 A i ,所以乱上课的话反而会使能力下降。贝西可以随意安排她的时间:滑雪、上课,或美美地喝上一杯可可汁。请问她如何安排上课和滑雪的时间,滑坡的次数才能达到最大?

    输入

    • 第一行:三个整数 T,S 和 N,1 ≤ T ≤ 10 4 ,1 ≤ S ≤ 100,1 ≤ N ≤ 10 4

    • 第二行到 S +1 行:第 i+1 行描述了第 i 门课程,分别为 M i ,L i 和 A i ,1 ≤ M i ,L i ≤ 10 4 ,1 ≤A i ≤ 100

    • 第 S + 2 行到 S + N + 1 行:第 S + i + 1 行描述了第 i 条斜坡,分别为 C i 和 D i ,1 ≤ C i ≤100,1 ≤ D i ≤ 10 4

    输出

    • 单个整数,表示贝西可以滑完的最大次数

    样例输入

    10 1 2 3 2 5 4 1 1 3

    样例输出

    6

    提示

    先滑 1 次二号斜坡,然后去上课,再去一号斜坡连滑 5 次

    题解:

    F[i][j] 表示第i秒能力值为j时的最大滑的次数

    然后背包,每次用合法状态(F[i][j]!=-1)去更新后面的状态

    但暴力dp过不了 加一个贪心优化掉10000

    Ft[j]表示能力值为<=j的最小滑坡时间,我们就不必枚举每一个滑坡去选最小的了.

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cmath>
     5 #include<cstring>
     6 using namespace std;
     7 const int N=10005,M=105;
     8 int gi(){
     9     int str=0;char ch=getchar();
    10     while(ch>'9' || ch<'0')ch=getchar();
    11     while(ch>='0' && ch<='9')str=str*10+ch-48,ch=getchar();
    12     return str;
    13 }
    14 int F[N][M];
    15 struct sor
    16 {
    17     int to,sta,l;
    18 }e[M];
    19 struct Chan
    20 {
    21     int l,lim;
    22 }c[N];
    23 bool comp(const sor &p,const sor &q){return p.sta<q.sta;}
    24 int n,s,m,last[M];
    25 int check(int x)
    26 {
    27     int l=1,r=s,mid;
    28     while(l<=r){
    29         mid=(l+r)>>1;
    30         if(e[mid].sta==x)return mid;
    31         if(e[mid].sta>x)r=mid-1;
    32         else l=mid+1;
    33     }
    34     return -1;
    35 }
    36 bool cmp(const Chan &p,const Chan &q){return p.lim<q.lim;}
    37 int pf(int x)
    38 {
    39     int ans,l=1,r=m,mid;
    40     while(l<=r){
    41         mid=(l+r)>>1;
    42         if(c[mid].lim<=x)ans=mid,l=mid+1;
    43         else r=mid-1;
    44     }
    45     return ans;
    46 }
    47 int ft[N];
    48 int getmin(int x)
    49 {
    50     int minn=1999999999;
    51     for(int i=1;i<=x;i++)
    52     if(c[i].l<minn)minn=c[i].l;
    53     return minn;
    54 }
    55 int main()
    56 {
    57     //freopen("pp.in","r",stdin);
    58     n=gi();s=gi();m=gi();
    59     int mh=0,minn=N;
    60     for(int i=1;i<=s;i++)
    61     {
    62         e[i].sta=gi();e[i].l=gi();e[i].to=gi();
    63         if(e[i].to>mh)mh=e[i].to;
    64     }
    65     sort(e+1,e+s+1,comp);
    66     for(int i=1;i<=m;i++){c[i].lim=gi(),c[i].l=gi();if(c[i].lim<minn)minn=c[i].lim;}
    67     sort(c+1,c+m+1,cmp);
    68     for(int i=1;i<=mh;i++)last[i]=pf(i);
    69     for(int i=1;i<=mh;i++)ft[i]=getmin(last[i]);
    70     memset(F,-1,sizeof(F));
    71     F[0][1]=0;
    72     int tmp,maxn=0;
    73     for(int i=0;i<n;i++)
    74     {
    75         tmp=check(i);
    76         maxn=0;
    77         for(int j=1;j<=mh;j++)
    78         {
    79             if(F[i][j]==-1)continue;
    80             F[i+ft[j]][j]=F[i][j]+1;
    81             if(F[i][j]>F[i+1][j])F[i+1][j]=F[i][j];
    82             if(tmp!=-1 && i+e[tmp].l<=n && F[i][j]>maxn)maxn=F[i][j];
    83         }
    84         if(tmp!=-1 && i+e[tmp].l<=n)F[i+e[tmp].l][e[tmp].to]=maxn;
    85     }
    86     int ans=0;
    87     for(int i=1;i<=mh;i++)if(F[n][i]>ans)ans=F[n][i];
    88     cout<<ans;
    89     return 0;
    90 }
  • 相关阅读:
    pdf 转图片,提取图片研究心得
    自己总结 C++ 代码规范
    Sublime Text 配置记录
    iOS控制器之基类设计
    SublimeText配置NodeJS代码提示
    YYCache设计思路及源码学习
    关于近期项目代码整理(iOS)
    iOS中iconfont(图标字体)的基本使用
    容器转场动画
    Xcode7 模拟器安装app (转)
  • 原文地址:https://www.cnblogs.com/Yuzao/p/6917388.html
Copyright © 2020-2023  润新知