P1353 [USACO08JAN]跑步Running
显然DP
发现跑完一段要一直休息到疲劳值为 0 ,所以可以把两个动作和在一起考虑,跑 j 分钟并休息 j 分钟
设 f [ i ] 表示跑到 i 时疲劳度为 0 时最大路程
那么枚举每个 j 进行转移就好了
一段时间的总路程可以用前缀和快速求出
代码简单不解释
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using namespace std; inline int read() { int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } return x*f; } const int N=10007; int n,m; int f[N],val[N],sum[N]; int main() { n=read(); m=read(); for(int i=1;i<=n;i++) val[i]=read(),sum[i]=sum[i-1]+val[i]; for(int i=0;i<n;i++) { for(int j=1;j<=m;j++) if(i+(j<<1)<=n) f[i+(j<<1)]=max(f[i+(j<<1)],f[i]+sum[i+j]-sum[i]); f[i+1]=max(f[i+1],f[i]); } printf("%d",f[n]); return 0; }