bzoj1613 / P1353 [USACO08JAN]跑步Running

P1353 [USACO08JAN]跑步Running

显然的dp

设$f[i][j]$表示进行到第$i$分钟时,$j$疲劳度下的最远距离,$d[i]$为第$i$分钟下能跑的距离

分类讨论

1.运动:显然$f[i][j]=max(f[i][j],f[i-1][j-1]+d[i])$

2.休息:我们枚举第$u(u<i)$分钟,休息到第$i$分钟时刚好疲劳度下降到$0$

显然$f[i][0]=max(f[i][0],f[i-u][u])$

注意疲劳度为$0$时仍可以继续休息,那么$f[i][0]=max(f[i][0],f[i-1][0])$

答案即为$f[n][0]$

复杂度$O(nm)$

end.

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cctype>
 5 #define re register
 6 using namespace std;
 7 void read(int &x){
 8     char c=getchar();x=0;
 9     while(!isdigit(c)) c=getchar();
10     while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
11 }
12 int max(int a,int b){return a>b?a:b;}
13 int min(int a,int b){return a<b?a:b;}
14 int n,m,d,f[10002][502];
15 int main(){
16     memset(f,128,sizeof(f)); f[0][0]=0;//初始最小化
17     read(n);read(m);
18     for(re int i=1;i<=n;++i){
19         read(d);//边读边做
20         f[i][0]=f[i-1][0];
21         for(re int j=min(m,i);j>=1;--j){//注意边界,倒序更新
22             f[i][j]=max(f[i][j],f[i-1][j-1]+d);
23             f[i][0]=max(f[i][0],f[i-j][j]);
24         }
25     }printf("%d",f[n][0]);
26     return 0;
27 }
View Code

 

posted @ 2018-10-27 12:00  kafuuchino  阅读(84)  评论(0编辑  收藏  举报