標籤:des style blog color io ar for div sp
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在時間限制內最多可以完成多少次滑雪。
題解:
動態規劃,定義f[i][j]代表在i時間,能力值為j的最多滑雪次數。
對應最後三種選擇:
①美美地喝上一杯可可汁 f[i][j]=f[i-1][j],
②上課 f[i][j]=f[上課前一個時刻][任意],
③滑雪 f[i][j]=f[i-po[j]][j]+1 (po[j]為能力值<=j的滑雪坡滑一次的最短用時)。
對於②可以在預先處理出ke[i][j]在i時刻結束,能力值達到j的課程的最晚開始時間。dp過程中處理出g[i]=max{f[i][j]}。
g[t]即為答案。
代碼:
#include<cstdio>#include<cstring>#include<algorithm>//by zrt//problem:using namespace std;int f[10005][105];int t,s,n;int ke[10005][105];int po[105];int g[10005];int main(){ #ifdef LOCAL freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); #endif memset(f,128,sizeof f); scanf("%d%d%d",&t,&s,&n); for(int i=1,m,l,a;i<=s;i++){ scanf("%d%d%d",&m,&l,&a); ke[m+l-1][a]=max(ke[m+l-1][a],m); } memset(po,0x3f,sizeof po); for(int i=1,c,d;i<=n;i++){ scanf("%d%d",&c,&d); for(int j=c;j<=100;j++){ po[j]=min(po[j],d); } } f[0][1]=0; g[0]=0; for(int i=1;i<=t;i++){ for(int j=1;j<=100;j++){ f[i][j]=f[i-1][j]; if(ke[i-1][j])f[i][j]=max(f[i][j],g[ke[i-1][j]]); if(i-po[j]>=0)f[i][j]=max(f[i][j],f[i-po[j]][j]+1); g[i]=max(g[i],f[i][j]); } } printf("%d\n",g[t]); return 0;}
BZOJ 1571: [Usaco2009 Open]滑雪課Ski