首页 > 技术文章 > 滑雪课程

huangdalaofighting 2017-06-06 11:02 原文

滑雪课程

时间限制: 1 Sec  内存限制: 128 MB

题目描述

贝西去科罗拉多州去滑雪,不过还她不太会玩,只是个能力为 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 次

题解:

first[t]表示能力要求小于等于t,所需时间最小的滑坡的时间, 

f[i]表示第i个课程开始之前,通过滑坡的最大数量

f[i]=max(f[j],第j个课程结束到第i个课程开始时间/first[A[j]])

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<queue>
#include<stack>
#include<ctime>
#include<vector>
using namespace std;
int f[101],first[101],t,n,m,c[100001],d[100001];
struct node
{
    int m,l,a;
}p[101];
bool cmp(const node a,const node b)
{
    if(a.m!=b.m)return a.m<b.m;
    else return a.l<b.l;
}
int main()
{
    int i,j;
    scanf("%d%d%d",&t,&m,&n);
    for(i=1;i<=m;i++)
        scanf("%d%d%d",&p[i].m,&p[i].l,&p[i].a);
    memset(first,127/3,sizeof(first));
    for(i=1;i<=n;i++)
    {
        scanf("%d%d",&c[i],&d[i]);
        first[c[i]]=min(first[c[i]],d[i]);
    }
    for(i=1;i<=100;i++)
    first[i]=min(first[i],first[i-1]);
    p[++m]=(node){0,0,1};
    p[++m]=(node){t,0,0};
    sort(p+1,p+m+1,cmp);
    for(i=2;i<=m;i++)
    {
        for(j=1;j<i;j++)
        {
            int y=p[i].m-(p[j].m+p[j].l);
            if(y>0)f[i]=max(f[i],f[j]+y/first[p[j].a]);
        }
    }
    cout<<f[m];
    return 0;
}

 

 

 

 

推荐阅读