P3622 [APIO2007]动物园
2021-01-04 04:28
标签:其他 olly 不同 cpp sizeof 朋友 也会 bit name 又是一个状压dp题 这个题比较考察思维 新建的圆形动物园是亚太地区的骄傲。圆形动物园坐落于太平洋的一个小岛上,包含一大圈围栏,每个围栏里有一 种动物。如下图所示: 你是动物园的公共主管。你要做的是,让每个来动物园的人都尽可能高兴。今天有一群小朋友来动物园参观,你希望能让他们在动物园度过一段美好的时光。但这并不是一件容易的事——有的动物有一些小朋友喜欢,有的动物有一些小朋友害怕。如,Alex 喜欢可爱的猴子和考拉,而害怕拥牙齿锋利的狮子。而Polly 会因狮子有美丽的鬃毛而喜欢它,但害怕有臭味的考拉。你可以选择将一些动物从围栏中移走以使得小朋友不会害怕。但你不能移走所有的动物,否则小朋友们就没有动物可看了。每个小朋友站在大围栏圈的外面,可以看到连续的 5 个围栏。你得到了所有小朋友喜欢和害怕的动物信息。当下面两处情况之一发生时,小朋友就会高兴: 至少有一个他害怕的动物被移走 例如,考虑下图中的小朋友和动物: 输入的第一行包含两个整数N ,C用空格分隔。 N是围栏数,C 是小朋友的个数。围栏按照顺时针的方向编号为1,2,3……n 接下来的C行,每行描述一个小朋友的信息E,F,L,F1,F2……,L1,L2…… F表示该小朋友害怕的动物数。 L表示该小朋友喜欢的动物数。 围栏F1,F2……中包含该小朋友害怕的动物。 Fi和Li是两两不同的整数,而且所表示的围栏都是该小朋友可以看到的。 小朋友已经按照他们可以看到的第一个围栏的编号从小到大的顺序排好了(这样最小的E对应的小朋友排在第一个,最大的E对应的小朋友排在最后一个)。 注意可能有多于一个小朋友对应的E是相同的。 仅输出一个数,表示最多可以让多少个小朋友高兴。 状压dp一样按照状压的套路去走 谢谢观看 P3622 [APIO2007]动物园 标签:其他 olly 不同 cpp sizeof 朋友 也会 bit name 原文地址:https://www.cnblogs.com/2004-08-20/p/13195799.html状压dp
So please 拿出一只不同颜色的笔和一个精神饱满的你 准备好脑子题目大意:
至少有一个他喜欢的动物没被移走
输入格式
其中E表示这个小朋友可以看到的第一个围栏的编号,换句话说,该小朋友可以看到的围栏为E,E+1,E+2,E+3,E+4 。注意,如果编号超过N将继续从1开始算。如:当N = 14 ,E = 13时,这个小朋友可以看到的围栏为 13,14,1,2和3。
围栏L1,L2……中包含该小朋友喜欢的动物。输出格式
样例输入
14 5
2 1 2 4 2 6
3 1 1 6 4
6 1 2 9 6 8
8 1 1 9 12
12 3 0 12 13 2
样例输出
5
算法分析
首先先找状态
则动态转移方程很容易就可以出来f[i][j] = max(f[i-1][(j&15)
首先第一维表示当前位置可以由上一个位置转移过来 i-1即上一个位置 而第二维((j&15)
状态一共就\(2^5\) 也就是32种情况 我们直接枚举就可以
我们已经知道了小朋友不喜欢和喜欢的动物 那我们可以将小朋友喜欢和不喜欢的动物用两个变量记录下来 fear表示不喜欢 love表示喜欢的
如果当前的状态j&fear为真或者~j&love为真 小朋友就会高兴(很有趣的位运算 建议自己推理 并不难)
我们用num[i][j]来记录在i这个位置j这个状态高兴的小盆友数 如果刚才两个判断条件有一个成立 就++num[i][j]
也很简单 我们用t来记录小朋友喜欢的动物的编号
减去e就是距离他所能看见的第一个动物的距离(为了状态枚举) 最后用+n然后%n的方式处理掉环的问题
t = (t-e+n)%n
一般来说我们到这里就可以打代码了
但是回忆一个地方
我们的动态转移方程是由上一个状态的后四位转移过来的 而这又是一个环 所以显然n的后四个和1的前四个状态必须一样
如果n的后四个为1111 而 1的前四个是0000 那显然会冲突(要把小动物劈成两半吗??!震惊),但是我们的代码并不会报错 反而会给出一个更优的值 但这个值是错误的
所以我们需要保证这个n的后四位必须由1前四位相同状态转移过来
所以我们可以把f[0]作为f[n]然后从f[0]的某个状态转移过来
将f的其他状态都设置为一个极小值只有当前状态是0 这样就可以保证其他状态的值绝对不会影响到我们的ans求解 也就能保证f[n]一定是由相同状态的f[1]转移过来的代码展示
#include
点个关注>_
文章标题:P3622 [APIO2007]动物园
文章链接:http://soscw.com/index.php/essay/39966.html