标签:其他 olly 不同 cpp sizeof 朋友 也会 bit name
又是一个状压dp题 这个题比较考察思维
So please 拿出一只不同颜色的笔和一个精神饱满的你 准备好脑子
新建的圆形动物园是亚太地区的骄傲。圆形动物园坐落于太平洋的一个小岛上,包含一大圈围栏,每个围栏里有一 种动物。如下图所示:
你是动物园的公共主管。你要做的是,让每个来动物园的人都尽可能高兴。今天有一群小朋友来动物园参观,你希望能让他们在动物园度过一段美好的时光。但这并不是一件容易的事——有的动物有一些小朋友喜欢,有的动物有一些小朋友害怕。如,Alex 喜欢可爱的猴子和考拉,而害怕拥牙齿锋利的狮子。而Polly 会因狮子有美丽的鬃毛而喜欢它,但害怕有臭味的考拉。你可以选择将一些动物从围栏中移走以使得小朋友不会害怕。但你不能移走所有的动物,否则小朋友们就没有动物可看了。每个小朋友站在大围栏圈的外面,可以看到连续的 5 个围栏。你得到了所有小朋友喜欢和害怕的动物信息。当下面两处情况之一发生时,小朋友就会高兴:
至少有一个他害怕的动物被移走
至少有一个他喜欢的动物没被移走
例如,考虑下图中的小朋友和动物:
输入的第一行包含两个整数N ,C用空格分隔。 N是围栏数,C 是小朋友的个数。围栏按照顺时针的方向编号为1,2,3……n
接下来的C行,每行描述一个小朋友的信息E,F,L,F1,F2……,L1,L2……
其中E表示这个小朋友可以看到的第一个围栏的编号,换句话说,该小朋友可以看到的围栏为E,E+1,E+2,E+3,E+4 。注意,如果编号超过N将继续从1开始算。如:当N = 14 ,E = 13时,这个小朋友可以看到的围栏为 13,14,1,2和3。
F表示该小朋友害怕的动物数。
L表示该小朋友喜欢的动物数。
围栏F1,F2……中包含该小朋友害怕的动物。
围栏L1,L2……中包含该小朋友喜欢的动物。
Fi和Li是两两不同的整数,而且所表示的围栏都是该小朋友可以看到的。
小朋友已经按照他们可以看到的第一个围栏的编号从小到大的顺序排好了(这样最小的E对应的小朋友排在第一个,最大的E对应的小朋友排在最后一个)。
注意可能有多于一个小朋友对应的E是相同的。
仅输出一个数,表示最多可以让多少个小朋友高兴。
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
状压dp一样按照状压的套路去走
首先先找状态
f[i][j] = max(f[i-1][(j&15)<<1],f[i-1][(j&15)<<1|1])+num[i][j];
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e4*5;
int f[maxn][40],num[maxn][40],ans;
int main(){
int n,m;scanf("%d%d",&n,&m);
for(int i = 1;i <= m;++i){
int e,l,f;
scanf("%d%d%d",&e,&f,&l);
int love = 0,fear = 0,t = 0;
for(int j = 1;j <= f;++j){
scanf("%d",&t);t = (t-e+n)%n;fear |= 1<<t;
}
for(int j = 1;j <= l;++j){
scanf("%d",&t);t = (t-e+n)%n;love |= 1<<t;
}
for(int j = 0;j < 32;++j){
if(((j&fear)||(~j&love)))++num[e][j];
}
}
for(int i = 0;i < 32;++i){
memset(f[0],128,sizeof(f[0]));f[0][i] = 0;
for(int j = 1;j <= n;++j)
for(int s = 0;s < 32;++s)
f[j][s] = max(f[j-1][(s&15)<<1],f[j-1][(s&15)<<1|1])+num[j][s];
if(ans < f[n][i])ans = f[n][i];
}
printf("%d\n",ans);
return 0;
}
谢谢观看
点个关注>_<
标签:其他 olly 不同 cpp sizeof 朋友 也会 bit name
原文地址:https://www.cnblogs.com/2004-08-20/p/13195799.html