滑雪课程
贝西去科罗拉多州去滑雪,不过还她不太会玩,只是个能力为 1 的渣渣。贝西从 0 时刻进入滑雪场,一到 T 时刻就必须离开。滑雪场里有 N 条斜坡,第 i 条斜坡滑行一次需要 Di 分钟,要求游客的能力达到 Ci 或以上时才能进入。贝西决心参加一些滑雪课程以提高自己的素质,这样可以在有限的时间内多滑几次坡。
滑雪场提供了 S 门课程。第 i 门课的开始时刻为 Mi,持续 Li 分钟,如果想参加课程,就不能迟到或早退。上完课之后,贝西的滑雪能力将变成 Ai。注意,不是能力增加 Ai,而是变成 Ai,所以乱上课的话反而会使能力下降。贝西可以随意安排她的时间:滑雪、上课,或美美地喝上一杯可可汁。请问她如何安排上课和滑雪的时间,滑坡的次数才能达到最大?
输入格式
• 第一行:三个整数 T,S 和 N,1 ≤ T ≤ 104; 1 ≤ S ≤ 100; 1 ≤ N ≤ 105
• 第二行到 S +1 行:第 i+1 行描述了第 i 门课程,分别为 Mi,Li 和 Ai,1 ≤ Mi;Li ≤ 104; 1 ≤Ai ≤ 100
• 第 S + 2 行到 S + N + 1 行:第 S + i + 1 行描述了第 i 条斜坡,分别为 Ci 和 Di,1 ≤ Ci ≤100; 1 ≤ Di ≤ 104
输出格式
• 单个整数,表示贝西可以滑完的最大次数
样例输入
10 1 2
3 2 5
4 1
1 3
样例输出
6
解释
先滑 1 次二号斜坡,然后去上课,再去一号斜坡连滑 5 次
首先我们预处理出对于每一个能力值可以滑的坡中所耗时间最少的(这样可以保证滑最多次数),用DP[i][j]表示当前在i时刻,能力值为j,
然后对于每一个状态我们可以做以下三个转移
1.什么都不做
DP[i][j]->DP[i+1][j]
2.上课(需要当前时间点有课可以上)
DP[i][j]->DP[i+该堂课的持续时间][该堂课对应的能力值]
3.滑雪
DP[i][j]->DP[i+当前能力值能滑的坡之中所耗时间最少的][j]
最后求最大次数即可。
题外话……这题的数据
超级弱,超级弱,真的,超级弱。我算法写错了能过9组……
1 #include <algorithm> 2 #include <iostream> 3 #include <cstdlib> 4 #include <cstring> 5 #include <fstream> 6 #include <cmath> 7 using namespace std; 8 ifstream fin("ski.in"); 9 ofstream fout("ski.out"); 10 int least[103]={0},DP[10003][103]={0}; 11 int lesson[103][3]={0},po[100003][2]={0}; 12 int tims[10003]={0}; 13 int ks=0,ps=0,xz=0; 14 int sear(int tim,int ene); 15 int main(void) 16 { 17 fin>>xz>>ks>>ps; 18 int a=0,b=0,c=0,most=0; 19 memset(DP,0xff,sizeof(DP)); 20 memset(least,0x7f,sizeof(least)); 21 for(int i=1;i<=ks;i++) 22 { 23 fin>>a>>b>>c; 24 lesson[i][0]=a; 25 lesson[i][1]=b; 26 lesson[i][2]=c; 27 tims[a]=i; 28 most=max(c,most); 29 } 30 for(int i=1;i<=ps;i++) 31 { 32 fin>>a>>b; 33 po[i][0]=a; 34 po[i][1]=b; 35 least[a]=min(least[a],b); 36 } 37 c=0x7fffffff; 38 for(int i=1;i<=most;i++) 39 { 40 least[i]=min(least[i],c); 41 if(least[i]<c)c=least[i]; 42 } 43 int ans=0; 44 ans=sear(0,1); 45 fout<<ans; 46 return 0; 47 } 48 49 int sear(int tim,int ene) 50 { 51 if(tim>xz)return 0; 52 if(DP[tim][ene]!=-1)return DP[tim][ene]; 53 int tot=0,ans=0; 54 tot=sear(tim+1,ene); 55 ans=max(tot,ans); 56 if(tims[tim]!=0)tot=sear(tim+lesson[tims[tim]][1],lesson[tims[tim]][2]); 57 ans=max(tot,ans); 58 if(tim+least[ene]<=xz)tot=sear(tim+least[ene],ene)+1; 59 ans=max(tot,ans); 60 DP[tim][ene]=ans; 61 return ans; 62 }