1 /*
2 题意:n<=1000, 2<=M<=10,Q<=M,求数组中的最大和,不存在连续的M个中超过Q个被选取
3 思路:状态压缩DP,枚举后面M个数的状态,dp[i][j/2]=max(dp[i-1][j],dp[i-1][j/2+(1<<(m-1))]+a[i])状态转移过程中需满足状态中1个个数小于Q
4 时间:2018.07.18
5 */
6 #include <bits/stdc++.h>
7 using namespace std;
8
9 typedef long long LL;
10 const int MAXN=100005;
11 const LL MOD7 = 1e9+7;
12
13 int qsize[(1<<10)+5];
14 int a[1005];
15 int dp[1005][(1<<10)+5];
16 int n,m,Q;
17
18 int lowbit(int x)
19 {
20 return x&(-x);
21 }
22 int Count(int x)
23 {
24 int res=0;
25 while (x>0)
26 {
27 ++res;
28 x-=lowbit(x);
29 }
30 return res;
31 }
32
33 void init()
34 {
35 qsize[0]=0;
36 for (int i=1;i<(1<<m);++i)
37 qsize[i]=Count(i);
38 }
39
40 int main()
41 {
42 #ifndef ONLINE_JUDGE
43 freopen("test.txt","r",stdin);
44 #endif // ONLINE_JUDGE
45 scanf("%d%d%d",&n,&m,&Q);
46 for (int i=1;i<=n;++i) scanf("%d",&a[i]);
47 init();
48 memset(dp,0,sizeof(dp));
49 int st = 1<<(m-1);
50 for (int i=1;i<=n;++i)
51 {
52 for (int j=0;j<(1<<m);++j)
53 {
54 if (qsize[j]<=Q) dp[i][j/2] = max(dp[i][j/2],dp[i-1][j]);
55 if (qsize[j]<=Q && qsize[j/2+st]<=Q) dp[i][j/2+st]=max(dp[i][j/2+st],dp[i-1][j]+a[i]);
56 }
57 }
58 // for (int i=1;i<=n;++i)
59 // {
60 // for (int j=0;j<(1<<m);++j)
61 // printf("dp[%d][%d]=%d\n",i,j,dp[i][j]);
62 // }
63 int ans=0;
64 for (int j=0;j<(1<<m);++j)
65 if (qsize[j]<=Q) ans = max(ans, dp[n][j]);
66 printf("%d\n",ans);
67 return 0;
68 }