本文版权归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. Ignatius and the Princess IV---hdu1029(动态规划或者sort)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1029 就是给你n(n是奇数)个数找出个数大于(n+1)/ 2 的那个数: n的取值范围是 n(1< ...

  2. Linux(5)- MariaDB、mysql主从复制、初识redis

    一.MYSQL(mariadb) MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可. 开发这个分支的原因之一是:甲骨文公司收购了MySQL后,有将MySQL ...

  3. sails ORM组件 Waterline v0.10 英文文档

    http://sailsdoc.swift.ren/ 这里有 sails中文文档 Introduction Installation Getting Started Models Data types ...

  4. 一种SPA(单页面应用)架构

    (如果对SPA概念不清楚的同学可以先自行了解相关概念) 平时喜欢做点小页面来玩玩,并且一直采用单页面应用(Single Page Application)的方式来进行开发.这种开发方式是在之前一年做的 ...

  5. RNNs

    什么是RNN网络? RNNs背后的主要目的是要使用序列本身的顺序信息.在传统的神经网络里,我们假设输入(输出)是条件独立的.但是,在许多任务里,这是个非常非常差的假设.如果你想预测一个序列中的下一个单 ...

  6. js 根据json数组中n个字段排序

    function compare(name, minor) { return function (o, p) { var a, b; if (o && p && typ ...

  7. idea配置scala和spark

    1 下载idea  路径https://www.jetbrains.com/idea/download/#section=windows 2安装spark  spark-2.1.0-bin-hadoo ...

  8. Html.DropDownListFor的用法总结

    在ASP.NET MVC中可以用DropDownListFor的方式来让用户选择已定列表中的一个数值. 注:重点是要将DropDownList的数据源转换成IEnumerable<SelectL ...

  9. Python编程题总结

    1 数学篇 1.1 斐波那契数列 def fib(n): if n in (0, 1): return n fib_n1, fib_n2 = 0, 1 for i in range(2, n + 1) ...

  10. spoj1811 LCS - Longest Common Substring

    地址:http://www.spoj.com/problems/LCS/ 题面: LCS - Longest Common Substring no tags  A string is finite ...