Description

  最近一直在为了学习算法而做题,这道题是初一小神犇让我看的。感觉挺不错于是写了写。

  这道题如果是一条线的话我们可以构造一个DP f[i,j]表示以i为起点,i,i+1...i+4的取与不取的状态的二进制为j然后1~i积累的答案

  以前几乎没有这么写过,因为很难想到j是没有后效性的

  前一个状态有两种情况,i-1位取,i-1位不取

  也就是f[i-1,j >> 1] f[i-1,j >> 1+1 << 4]

  然后小朋友要怎么处理才能做到不重复不遗漏呢

  答案是记录以每个点为起点,连着5位的状态为j时从那个点出发的小朋友的开心个数

  显然当我们知道连着5位的状态时,完全可以推出该小朋友开不开心

  这一部分很容易脑补 但是真正写起来用位运算比较方便

  而i-1位是否取对当前也是没有影响的,所以这个DP就可以敲起来啦

  

  但是如何处理环形?

  固定前4位的取与不取的状态就可以啦...

  最后的时间复杂度就是DP状态的O(2^5*C)

  处理环的代价是O(2^4)

  最后是O(2^9*C) C<=5*10^5

  对于10s的时限来说还是可以过哒~

 /**************************************************************
Problem: BZOJ1151
Author: mjy0724
Time:3760 ms
Memory:30336 kb
****************************************************************/ program bzoj1151;
const maxn=;
var i,j,x,n,c:longint;
e,h,l,next,link:array[-..maxn]of longint;
hate,love:array[-..maxn,-..]of boolean;
num,f:array[-..maxn,-..]of longint; function max(a,b:longint):longint;
begin
if a>b then exit(a) else exit(b);
end; procedure solve_num;
var i,j,k,t:longint;
begin
fillchar(num,sizeof(num),);
for i:= to n do
for j:= to do
begin
k:=link[i];
while k<> do
begin
for t:= to do if (j and ( << (-t)))<> then
//这个位运算刚开始一直出错,不能写成=1因为and之后虽然只有1位是1但是不一定在最后一位QAQ
begin
if love[k,t] then
begin
inc(num[i,j]);break;//这里的break很重要 因为1个小朋友只能算一次
end;
end else
begin
if hate[k,t] then
begin
inc(num[i,j]);break;
end;
end;
k:=next[k];
end;
end;
end; procedure dp;
var head,i,j,tot,k,ans:longint;
begin
ans:=;
for head:= to do//枚举前4位的状态
begin
fillchar(f,sizeof(f),);
fillchar(f[],sizeof(f[]),);
for i:= to do
for j:=(head << i) and to (head << i) and + << i- do //and 31是小小的位运算技巧,把前面的头都去掉啦
f[i,j]:=max(f[i-,j >> ],f[i-,j >> + << ])+num[i,j]; for i:= to n- do
for j:= to do
f[i,j]:=max(f[i-,j >> ],f[i-,j >> + << ])+num[i,j];
tot:=;
for i:=n- to n do
begin
inc(tot);
for k:= to << (-tot)- do
begin
j:=k << tot+head >> (n-i);
f[i,j]:=max(f[i-,j >> ],f[i-,j >> + << ])+num[i,j];
end;
end; for i:= to do ans:=max(ans,f[n,i]);
end;
writeln(ans);
end; begin
readln(n,c);
fillchar(hate,sizeof(hate),false);
fillchar(love,sizeof(love),false);
for i:= to c do
begin
read(e[i],h[i],l[i]);
for j:= to h[i] do
begin
read(x);
if x>=e[i] then hate[i,x-e[i]+]:=true else hate[i,(x+n-e[i]) mod n+]:=true;//这里处理环的情况 表示第i个小朋友视野里的第几个是否讨厌
end;
for j:= to l[i] do
begin
read(x);
if x>=e[i] then love[i,x-e[i]+]:=true else love[i,(x+n-e[i]) mod n+]:=true;
end;
readln;
next[i]:=link[e[i]];link[e[i]]:=i;
end;
solve_num;
dp;
end.

[BZOJ1151][CTSC2007]动物园zoo 解题报告|DP|位运算的更多相关文章

  1. [bzoj1151][CTSC2007]动物园zoo_状压dp

    动物园zoo 题目大意:https://www.lydsy.com/JudgeOnline/problem.php?id=1151 题解: 我们发现每个点只会往右延伸$5$个,这个数非常小. 再加上每 ...

  2. 2018.09.08 bzoj1151: [CTSC2007]动物园zoo(状压dp)

    传送门 状压dp好题啊. 可以发现这道题的状压只用压缩5位. f[i][j]表示当前在第i个位置状态为j的最优值. 显然可以由f[i-1]更新过来. 因此只用预处理在第i个位置状态为j时有多少个小朋友 ...

  3. 基于DP+位运算的RMQ算法

    来源:http://blog.csdn.net/y990041769/article/details/38405063 RMQ算法,是一个快速求区间最值的离线算法,预处理时间复杂度O(n*log(n) ...

  4. 【[APIO/CTSC2007]动物园】状压DP

    题目测评:https://www.luogu.org/problemnew/show/P3622 题目描述 新建的圆形动物园是亚太地区的骄傲.圆形动物园坐落于太平洋的一个小岛上,包含一大圈围栏,每个围 ...

  5. bzoj 1151: [CTSC2007]动物园zoo

    思路:因为每个人最多只能看到五个动物,我们考虑将其状压,f[ i ][ s ] 表示到了第 i 个位置, i, i + 1, i + 2, i + 3, i + 4这四个动物的状态为s, 此时的最大值 ...

  6. ACM: HDU 1028 Working out 解题报告-DP

    Working out time limit per test  2 seconds memory limit per test  256 megabytes input  standard inpu ...

  7. [CTSC2007]动物园zoo

    link 试题分析 发现每个小朋友最多只能看到$5$个动物所以考虑状压$dp$.我们定义$f(i,j)$为第$i$个位置从此往后$5$个人的最喜欢数量.所以只要预处理出对于每个点从后$5$个会让多少小 ...

  8. [jzoj 6073] 河 解题报告 (DP)

    interlinkage: https://jzoj.net/senior/#main/show/6073 description: solution: 考虑一条河$x$被染的效果 显然对于一条河$i ...

  9. [jzoj 5661] 药香沁鼻 解题报告 (DP+dfs序)

    interlinkage: https://jzoj.net/senior/#contest/show/2703/0 description: solution: 注意到这本质就是一个背包,只是选了一 ...

随机推荐

  1. redis学习资料汇总

    redis学习资料汇总 2017年01月07日 22:10:37 阅读数:281 转载:http://blog.csdn.net/wtyvhreal/article/details/50427627 ...

  2. mvc4 Forms验证存储 两种登录代码

    自己也不知道网上看到的第一种居多,第二种用到的人很少,第二种代码十分简洁,就是不清楚是否有安全隐患. 要采用Forms身份验证,先要在应用程序根目录中的Web.config中做相应的设置: <a ...

  3. OpenCV入门:(六:基础画图函数)

    有时程序中需要画一些基础的图形,例如直线,矩形,椭圆以及多边形.OpenCV中当然有此类函数. 1.函数介绍 直线line: , , ) img – 图像 pt1 – 直线起点 pt2 – 直线终点 ...

  4. 2.Linux文件和目录

    1. 目录和路径 linux下比较特殊的目录: . 代表此层目录 .. 代表上一层目录 - 代表前一个工作目录 ~ 代表『目前使用者身份』所在的home目录 ~account 代表 account 这 ...

  5. NMON记录服务器各项性能数据

    1.将下载下来的nmon文件通过ftp传入服务器下,将nmon权限全开chmod +x nmon 2.查看nmon可以看到如下内容 查看各项指标 输入C,CPU数据 M,内存 N,网络 D,磁盘 T, ...

  6. JVM 什么时候会触发FGC

    1:System.gc(); 2:老年代满了 没啥好说的从年轻代去往老年代的 3:JDK7或JDK6中永久区满了 得看是否还会有分配,如果没有就不会进行FGC,不过CMS GC下会看到不停地CMS G ...

  7. 语法测试cnblogs使用Markdown

    参考自作业部落Cmd Markdown 编辑器 https://www.zybuluo.com 欢迎使用 Cmd Markdown 编辑阅读器 什么是 Markdown Markdown 是一种方便记 ...

  8. URAL 1736 Chinese Hockey(网络最大流)

    Description Sergey and Denis closely followed the Chinese Football Championship, which has just come ...

  9. python基础之删除文件及删除目录的方法

    下面来看一下python里面是如何删除一个文件及文件夹的~~ 1 2 3 4 5 6 7 8 #首先引入OS模块 import os #删除文件:  os.remove() #删除空目录:  os.r ...

  10. 阿里云服务器 linux下载 jdk

    直接从本地下载包上传比较慢.直接在服务器上下载安装包: 1.进入orcle官网; 2.选择需要下载的版本,下载需要同意orcle协议, 3.点击下载,获取到下载请求的cookie, 复制所有cooki ...