DP练习 巡逻

 国庆这天五一大道上人头攒动,这是因为大家都准备从五一广场上那个大屏幕观看新中国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;
}

 

 
 
posted @ 2016-05-12 22:14  csgc0131123  阅读(497)  评论(0编辑  收藏  举报