1571: [Usaco2009 Open]滑雪课Ski

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次第一个滑雪坡。

 

Source

 
 
显然是一道DP。。。
不过要用当前状态去更新别的状态。。。
首先有一个显而易见而又没什么卵用的优化。。那就是对于同一个能力值的坡,肯定时间越短越好,也就是说,每个能力值滑的坡都是固定的。。。这个可以通过一次桶排序求出来。。。
然后来写一个状态转移方程
f[i][j]表示i时刻能力值为j滑的次数
①当时刻i是课程j的结束时间则f[i][lesson[j].w(能力值)]=max(f[lesson[j].begin][t])
t表示lesson[j].begin时刻的能力值。。。可以枚举,也可以在读入的时候通过一次桶排序得出
②在第i时刻滑雪则
f[i+slope[j]][t]=max(f[i][t]+1);
然后就可以得出答案了。。。
当然这道题的时间要从0开始算。。。不然会wa两个点。。。
 4 #include<iostream>
 5 #include<cstdlib>
 6 #include<cmath>
 7 #include<cstring>
 8 #include<cstdio>
 9 #include<algorithm>
10 #include<string>
11 #include<map>
12 #include<queue>
13 #include<vector>
14 #include<set>
15 #define mod 1000000007
16 #define inf 1000000000
17 #define maxn 30005
18 #define maxm 30005*2
19 #define eps 1e-10
20 #define ll long long
21 #define for0(i,n) for(int i=0;i<=(n);i++)
22 #define for1(i,n) for(int i=1;i<=(n);i++)
23 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
24 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
25 #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)
26 using namespace std;
27 struct lesson{
28     int m,l,a,r;
29 }e[110];
30 int t1[110],t2[maxn],s1[maxn],s2[maxn],f[maxn][110];//s1能力值为i时最短的坡,s2为i时刻最大的能力值 
31 int read(){
32     int x=0,f=1;char ch=getchar();
33     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
34     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
35     return x*f;
36 }
37 bool cmp(lesson a,lesson b){
38     return a.r<b.r;
39 }
40 int main(){
41     freopen("input.txt","r",stdin);
42     freopen("output.txt","w",stdout);
43     int t=read(),s=read(),n=read();
44     for1(i,s){
45         e[i].l=read();e[i].m=read();e[i].a=read();
46         e[i].r=e[i].m+e[i].l;
47         t2[e[i].r]=max(t2[e[i].r],e[i].a);
48     }
49     s2[0]=1;
50     for1(i,t){
51         s2[i]=max(s2[i-1],t2[i]);
52     }
53     for0(i,110)t1[i]=inf;s1[0]=inf;
54     for1(i,n){
55         int c=read(),d=read();
56         t1[c]=min(d,t1[c]);
57     }
58     for1(i,110)s1[i]=min(s1[i-1],t1[i]);
59     sort(e+1,e+s+1,cmp);
60     int cnt=1;
61     for0(i,t){
62         while(i==e[cnt].r){
63             for1(j,s2[e[cnt].l+1])
64                 f[i][e[cnt].a]=max(f[i][e[cnt].a],f[e[cnt].l+1][j]);
65             cnt++;
66         }
67         for1(j,s2[i]){
68             f[i+s1[j]][j]=max(f[i+s1[j]][j],f[i][j]+1);
69         }
70     }
71     int ans=0;
72     for1(i,s2[t])
73         ans=max(ans,f[t][i]);
74     printf("%d",ans);
75     return 0;
76 }
View Code

 

posted @ 2016-03-17 15:17  HTWX  阅读(135)  评论(0编辑  收藏  举报