本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作。

本文作者:ljh2000
作者博客:http://www.cnblogs.com/ljh2000-jump/
转载请注明出处,侵权必究,保留最终解释权!

题目链接:CF796E

正解:$DP$

解题报告:

  考虑用$f[i][j][x][y]$表示考虑完前$i$个问题,当前总共用了$j$次机会,对于第一个人还能看$x$道题,第二个人还能看$y$道题的最优值,考虑$x$和$y$等于$0$的情况,直接转移就好了。

  这里写转出可能会方便一些。

  注意到这个复杂度是$O(npk^2)$的,但是当$p>\frac{2*n}{k}$时,可以全选,那么直接全选就好了,特判一下,所以复杂度是$O(n^2k)$。

//It is made by ljh2000
//有志者,事竟成,破釜沉舟,百二秦关终属楚;苦心人,天不负,卧薪尝胆,三千越甲可吞吴。
#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#include <cstdio>
#include <string>
#include <queue>
#include <cmath>
#include <ctime>
#define lc root<<1
#define rc root<<1|1
#define rep(i,j,k) for(int i=j;i<=k;i++)
#define reg(i,x) for(int i=first[x];i;i=next[i])
using namespace std;
typedef long long LL;
const int MAXN = 1002;
int n,p,k,a[MAXN],b[MAXN],ans;
int n1,n2,f[2][MAXN][52][52];
//f[i][j][x][y]表示考虑完前i个问题,当前总共用了j次机会,第一个人还能看x道题,第二个人还能看y道题的最优值
inline void upd(int &x,int y){ if(y>x) x=y; }
inline int getint() {
int w=0,q=0; char c=getchar(); while((c<'0'||c>'9') && c!='-') c=getchar();
if(c=='-') q=1,c=getchar(); while (c>='0'&&c<='9') w=w*10+c-'0',c=getchar(); return q?-w:w;
} inline void work(){
n=getint(); p=getint(); k=getint();
n1=getint(); for(int i=1;i<=n1;i++) a[getint()]++;
n2=getint(); for(int i=1;i<=n2;i++) b[getint()]++;
int lim=n/p; if(n%p!=0) lim++; lim<<=1;
if(k>=lim) {
//printf("%d",n1+n2);
for(int i=1;i<=n;i++) ans+=a[i]|b[i];
printf("%d",ans);
return ;
} memset(f,-0x3f,sizeof(f)); f[0][0][0][0]=0; int to,tag=1;
for(int i=1/*!!!*/;i<=n;i++) {
to=tag; memset(f[to],-0x3f,sizeof(f[to]));//!!!
tag^=1;
for(int j=0;j<=p;j++) {
for(int ii=0;ii<=k;ii++) {
for(int jj=0;jj<=k;jj++) {
if(!ii && !jj) {
upd(f[to][j][0][0],f[tag][j][0][0]);
upd(f[to][j+1][k-1][0],f[tag][j][0][0]+a[i]);
upd(f[to][j+1][0][k-1],f[tag][j][0][0]+b[i]);
upd(f[to][j+2][k-1][k-1],f[tag][j][0][0]+(a[i]|b[i]));
}
else if(!ii) {
upd(f[to][j][0][jj-1],f[tag][j][0][jj]+b[i]);
upd(f[to][j+1][k-1][jj-1],f[tag][j][0][jj]+(a[i]|b[i]));
upd(f[to][j+2][k-1][k-1],f[tag][j][0][jj]+(a[i]|b[i]));
}
else if(!jj) {
upd(f[to][j][ii-1][0],f[tag][j][ii][0]+a[i]/*!!!*/);
upd(f[to][j+1][ii-1][k-1],f[tag][j][ii][0]+(a[i]|b[i]));
upd(f[to][j+2][k-1][k-1],f[tag][j][ii][0]+(a[i]|b[i]));
}
else upd(f[to][j][ii-1][jj-1],f[tag][j][ii][jj]+(a[i]|b[i]));
}
}
}
}
tag^=1;
for(int l=0;l<=p;l++)
for(int i=0;i<=k;i++)
for(int j=0;j<=k;j++)
ans=max(ans,f[tag][l][i][j]);
printf("%d",ans);
} int main()
{
#ifndef ONLINE_JUDGE
freopen("796.in","r",stdin);
freopen("796.out","w",stdout);
#endif
work();
return 0;
}
//有志者,事竟成,破釜沉舟,百二秦关终属楚;苦心人,天不负,卧薪尝胆,三千越甲可吞吴。

  

codeforces796E Exam Cheating的更多相关文章

  1. Codeforces 796E - Exam Cheating(dp)

    Codeforces 题目传送门 & 洛谷题目传送门 当被数据结构搞自闭的 tzc 信心满满地点开一道 *2400 的 dp 题时-- 却发现自己不会做?! 这足以证明蒟蒻 dp 之菜/dk/ ...

  2. Codeforces Round #408 (Div. 2)

    C. Bank Hacking 题目大意:给出一棵n个节点的树,每个节点有一个权值,删掉一个点的代价为当前这个点的权值,并且会使其相邻点和距离为2且中间隔着未被删除的点的点权值加1,现在选一个点开始删 ...

  3. Codeforces Round #408 (Div. 2) 题解【ABCDE】

    A - Buying A House 题意:给你n个房间,妹子住在第m个房间,你有k块钱,你想买一个离妹子最近的房间.其中相邻的房间之间距离为10,a[i]=0表示已经被别人买了. 题解:扫一遍更新答 ...

  4. Codeforces Round #408( Div2)

    Bank Hacking 阅读题,读完之后手算一下可以发现每一个bank被hack所需要的strength无非分为三种情况. 1. $a_i$,当且仅当i为第一个选择的点. 2. $a_i+1$,当且 ...

  5. Linux学习之Exam系统发布

    配置时间:2015年11月27日 配置人:撰写人:微冷的雨   Happy 01.Linux安装图 欢迎页面 桌面 02.Linux命令之文件目录操作 给北大青鸟五道口校区创建三个机房(L4,L5,L ...

  6. CF534A Exam 构造

    An exam for n students will take place in a long and narrow room, so the students will sit in a line ...

  7. CF Exam (数学)

     Exam time limit per test 1 second memory limit per test 256 megabytes input standard input output s ...

  8. Exam 70-462 Administering Microsoft SQL Server 2012 Databases 复习帖

    好吧最近堕落没怎么看书,估计这个月前是考不过了,还是拖到国庆之后考试吧.想着自己复习考试顺便也写点自己的复习的概要,这样一方面的给不准备背题库的童鞋有简便的复习方法(好吧不被题库的同学和我一样看MSD ...

  9. Final Exam Arrangement(ZOJ)

    In Zhejiang University, there are N different courses labeled from 1 to N. Each course has its own t ...

随机推荐

  1. lua相关库安装常见问题

    一.先安装lua brew install lua 我本机的安装路径为:/usr/local/Cellar/lua/5.3.4_2 二.安装luarocks 下载luarocks的安装包: http: ...

  2. golang 发送多人邮件 textproto.Error{Code:554, Msg:"Transaction failed: Illegal semicolon, not in group"

    网上很多版本发送邮件都是用; 号,关键在于,多个邮件分割不能用; 号,需要用,号 // send mail func SendMail(subject string, message string, ...

  3. DNS 知识点

    总结: DNS解析过程:主机查看本地缓存,然后向本地域名服务器进行递归查询,本地域名服务器向根,顶级,权限进行迭代查询   DNS 解析过程: 1.查看浏览器缓存 2.查看os缓存         w ...

  4. 前端 javascript 数据类型 布尔类型

    python 是大写 True javascript 是小写 true false 也是 布尔类型仅包含真假,与Python不同的是其首字母小写. ==      比较值相等 !=       不等于 ...

  5. java-mybaits-00503-延迟加载

    1.什么是延迟加载 resultMap可以实现高级映射(使用association.collection实现一对一及一对多映射),association.collection具备延迟加载功能. 需求: ...

  6. 如何停止requestAnimationFrame方法启动的动画

    HTML5/CSS3时代,我们要在web里做动画选择其实已经很多了:(1) 你可以用CSS3的animattion+keyframes;(2) 你也可以用css3的transition; (3) 你还 ...

  7. 工作中发现Web服务器的磁盘满后故障分析

    遇到的问题:   今天收到报警,某台线上的服务器的磁盘已满,但是登上去使用du -sh /log/* 检查, 发现文件的大小远远小于磁盘的空间,此时不知道该如何解决! 解决的方法:   其实,如果只是 ...

  8. 数据库连接池libzdb

    官网:http://www.tildeslash.com/libzdb/ A small, easy to use Open Source Database Connection Pool Libra ...

  9. Python eval() 的使用:将字符串转换为列表,元祖,字典

    eval() 函数用来执行一个字符串表达式,并返回表达式的值. 语法 以下是 eval() 方法的语法: eval(expression[, globals[, locals]]) 参数 expres ...

  10. HDU - 5909 Tree Cutting (树形dp+FWT优化)

    题意:树上每个节点有权值,定义一棵树的权值为所有节点权值异或的值.求一棵树中,连通子树值为[0,m)的个数. 分析: 设\(dp[i][j]\)为根为i,值为j的子树的个数. 则\(dp[i][j\o ...