#include <bits/stdc++.h>
using namespace std;
int n,p,k,x,now,ans,pp;
int a[1005],b[1005];
int main(){
scanf("%d%d%d",&n,&p,&k);
scanf("%d",&x); while (x--) scanf("%d",&now),a[now]=1;
scanf("%d",&x); while (x--) scanf("%d",&now),b[now]=1;
pp=n/k; if (n%k) pp++; pp<<=1; p=min(p,pp);
//可以想到,如果偷看次数过多而每次能看得连续题目也不少,其实是没有必要的
//所以应该重新计算一个p值,可以减少枚举
int f[p+5][k+5][k+5],g[p+5][k+5][k+5];
//写了个暴力计算了一下,发现当p为42,j为49时
//第一次这样开数组 ,虽然洛谷上是动态赋值的,cf应该也是动态赋值的,但是为了响应本地还是这样保险
//f[i][j][x][y]: 前i题,看了j次,左边还能连续看x题,右边还能连续看y题时,最多看到的题数
memset(f,-60,sizeof(f));
f[0][0][0]=0;
for (register int i=1; i<=n; ++i)
{
memcpy(g,f,sizeof(f)); memset(f,-60,sizeof(f));
for (register int j=0; j<=p; ++j)
for (register int ii=0; ii<=k; ++ii)
for (register int jj=0; jj<=k; ++jj)
{
if (!ii && !jj)
{
f[j][0][0]=max(f[j][0][0],g[j][0][0]);
f[j+1][k-1][0]=max(f[j+1][k-1][0],g[j][0][0]+a[i]);
f[j+1][0][k-1]=max(f[j+1][0][k-1],g[j][0][0]+b[i]);
f[j+2][k-1][k-1]=max(f[j+2][k-1][k-1],g[j][0][0]+(a[i]|b[i]));
}
if (!ii && jj)
{
f[j][0][jj-1]=max(f[j][0][jj-1],g[j][0][jj]+b[i]);
f[j+1][k-1][jj-1]=max(f[j+1][k-1][jj-1],g[j][0][jj]+(a[i]|b[i]));
}
if (ii && !jj)
{
f[j][ii-1][0]=max(f[j][ii-1][0],g[j][ii][0]+a[i]);
f[j+1][ii-1][k-1]=max(f[j+1][ii-1][k-1],g[j][ii][0]+(a[i]|b[i]));
}
if (ii && jj)
{
f[j][ii-1][jj-1]=max(f[j][ii-1][jj-1],g[j][ii][jj]+(a[i]|b[i]));
}
}
}
for (register int i=0; i<=p; ++i)
for (register int j=0; j<=k; ++j)
for (register int jj=0; jj<=k; ++jj) ans=max(ans,f[i][j][jj]);
printf("%d\n",ans);
return 0;
}
CF796E Exam Cheating
最新推荐文章于 2021-11-12 22:45:24 发布