滑雪课程
时间限制: 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; }