1. 程式人生 > >bzoj 1571 [Usaco2009 Open]滑雪課Ski

bzoj 1571 [Usaco2009 Open]滑雪課Ski

problem 之前 output php source arch nbsp tin open

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

Gold

思路: 本題是動態規劃,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

bzoj 1571 [Usaco2009 Open]滑雪課Ski