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
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 }