国庆这天五一大道上人头攒动,这是因为大家都准备从五一广场上那个大屏幕观看新中国60周年的国庆阅兵式!这虽然是一件很喜庆的事情,可却让CS市的警察局长伤透了脑筋的,因为人潮拥挤是很容易发生安全事故的。
为了防止意外以及能够及时处理安全问题。他们特意将五一大道上分成了N等份,每一份设置一个群众集会点,总共有N个集会点。在国庆这天每个聚集点都会聚集一定数量的群众,而同时也会有警察来管理这些集会点。因为CS其他很多地方都需要巡逻,所以只有有限的M个警察能够被分配到了五一大道上,而他们的能力也有限,一个人只能管理连续的K个集会点。
现在给你每个集会点将要聚集的群众人数,你能告诉警察他们最多能够管理到多少群众吗?
如有10个集会点,3个警察,每个警察能管理连续2个集会点。
10 5 34 4 26 12 75 15 8 20 所以最多能够管理到167个群众。
#include<iostream> using namespace std; #include<cstdio> #include<cstring> int n,m,k; #define N 1010 int f[N][N],s[N]={0}; int ans=0; int main() { freopen("manage.in","r",stdin); freopen("manage.out","w",stdout); scanf("%d%d%d",&n,&m,&k); for(int i=1;i<=n;++i) { scanf("%d",&x); s[i]=s[i-1]+x; } memset(f,0,sizeof(f)); for(int i=1;i<=n;++i)/*类似于背包问题*/ for(int j=1;j<=m;++j) for(int l=1;l<=k&&i-l>=0;++l)/*对于f[i][j]表示的是前i个集会,j个警察所能管理的最大人数*/ f[i][j]=max(f[i-1][j],f[i-l][j-1]+s[i]-s[i-l]);/*f[i][j]是第i个集会管还是不管,不管就是f[i-1][j],f[i-l][j-1]+s[i]-s[i-l]表示的第j个警察,管理l个集会,为什么不是管理k个呢?因为i-k有可能越界*/ cout<<f[n][m]<<endl; fclose(stdin); fclose(stdout); return 0; }