滑雪课程
贝西去科罗拉多州去滑雪,不过还她不太会玩,只是个能力为 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 }
View Code

 

 posted on 2016-07-01 16:51  SakuLeaF  阅读(400)  评论(0编辑  收藏  举报