bzoj 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

思路: 本题是动态规划,f[i][j]表示到时刻i,并且能力为j,此时最多滑的次数。此题还是向后转移比较方便。 
 1 #include<bits/stdc++.h>
 2 using namespace std;  
 3 #define R register int
 4 #define rep(i,a,b) for(R i=a;i<=b;i++)  
 5 #define Rep(i,a,b) for(R i=a;i>=b;i--)  
 6 #define ms(i,a)    memset(a,i,sizeof(a))  
 7 #define gc()       getchar()  
 8 template<class T>void read(T &x){
 9     x=0; char c=0;  
10     while (!isdigit(c)) c=gc();  
11     while (isdigit(c)) x=x*10+(c^48),c=gc();  
12 }
13 int const N=10000+3;  
14 int const M=100+3;  
15 int const inf=1e8;  
16 struct Edge{
17     int to,nt,w;  
18 }E[M];  
19 int cnt,H[N],t,s,n,c[N],d[N],f[N][M],g[M];  
20 void add(int a,int b,int c){
21     E[cnt]=(Edge){b,H[a],c}; H[a]=cnt++;  
22 }
23 int main(){
24     read(t); read(s) ;read(n);  
25     ms(-1,H);  
26     while (s--){
27         int x,y,z;  
28         read(x); read(y); read(z);  
29         add(x,x+y,z);  
30     }
31     rep(i,0,100) g[i]=inf;  
32     rep(i,1,n) read(c[i]),read(d[i]),g[c[i]]=min(g[c[i]],d[i]);  
33     rep(i,1,100) g[i]=min(g[i],g[i-1]);  
34     ms(-1,f);  
35     f[0][1]=0;   
36     rep(i,0,t)rep(j,1,100) if(f[i][j]>-1) {
37         f[i+1][j]=max(f[i+1][j],f[i][j]); 
38         for(R k=H[i];k!=-1;k=E[k].nt){
39             int v=E[k].to;  
40             if(E[k].w<=j) continue;  
41             if(v>t) continue;  
42             f[v][E[k].w]=max(f[v][E[k].w],f[i][j]);  
43         }
44         if(i+g[j]<=t) f[i+g[j]][j]=max(f[i+g[j]][j],f[i][j]+1);  
45     } 
46     int ans=0;  
47     rep(i,0,100) ans=max(ans,f[t][i]); 
48     cout<<ans<<endl; 
49     return 0; 
50 }
View Code

 

posted @ 2019-03-19 16:40  zjxxcn  阅读(156)  评论(0编辑  收藏  举报