1596:动物园
时间限制: 1000 ms 内存限制: 524288 KB
【题目描述】
原题来自:APIO 2007
新建的圆形动物园是亚太地区的骄傲。圆形动物园坐落于太平洋的一个小岛上,包含一大圈围栏,每个围栏里有一种动物。如下图所示:
你是动物园的公关主管。你要做的是,让每个参观动物园的游客都尽可能高兴。今天有一群小朋友来到动物园参观,你希望能让他们在动物园度过一段美好的时光。但这并不是一件容易的事——有些小朋友喜欢某些动物,而有些小朋友则害怕某些动物。例如, Alex 喜欢可爱的猴子和考拉,而害怕拥有锋利牙齿的狮子。而 Polly 会因狮子有美丽的鬃毛而喜欢它,但害怕有臭味的考拉。
你可以选择将一些动物从围栏中移走以使得小朋友不会害怕。但你移走的动物也不能太多,否则留给小朋友们观赏的动物就所剩无几了。
每个小朋友站在大围栏圈的外面,可以看到连续的 个围栏。你得到了所有小朋友喜欢和害怕的动物信息。当下面两处情况之一发生时,小朋友就会高兴:
1、至少有一个他害怕的动物被移走;
2、至少有一个他喜欢的动物没被移走。
例如,考虑下图中的小朋友和动物:
假如你将围栏 中的动物都保留了。但是,Polly 和 Hwan 将不高兴,因为他们看不到任何他们喜欢的动物,而他们害怕的动物都还在。这种安排方式使得三个小朋友高兴。
现在换一种方法,如果你将围栏 12 而高兴。唯一不高兴的只有 Ka-Shu。
如果你只移走围栏 5 个小朋友会高兴。这种方法使得了最多的小朋友高兴。
【输入】
输入的第一行包含两个整数 1,2,3,…,N。
接下来的 。
其中3。
L 表示该小朋友喜欢的动物数。
围栏 中包含该小朋友喜欢的动物。
是两两不同的整数,而且所表示的围栏都是该小朋友可以看到的。
【输出】
仅输出一个数,表示最多可以让多少个小朋友高兴。
小朋友已经按照他们可以看到的第一个围栏的编号从小到大的顺序排好了(这样最小的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
【提示】
样例说明 1
样例 )高兴。
样例输入 2
12 7 1 1 1 1 5 5 1 1 5 7 5 0 3 5 7 9 7 1 1 7 9 9 1 1 9 11 9 3 0 9 11 1 11 1 1 11 1
样例输出 2
6
样例说明 2
样例 )都高兴是不可能的。
数据范围与提示:
对于每一个测试点,如果你的答案正确,则该测试点得满分,否则得 0 分。
对于全部数据,。
sol:首先由题解可知这是一道状压dp好题。
令dp[i][j]表示以i为开头的5个动物以状态为j时最多能让多少小朋友快乐(需要在每个小朋友的位置E上预处理出使E,E+1,~,E+5状态为j时的快乐人数),然后先暴力枚举(n-3~n的状态)之后n*32转移就可以了
#include <bits/stdc++.h> using namespace std; typedef int ll; inline ll read() { ll s=0; bool f=0; char ch=' '; while(!isdigit(ch)) { f|=(ch=='-'); ch=getchar(); } while(isdigit(ch)) { s=(s<<3)+(s<<1)+(ch^48); ch=getchar(); } return (f)?(-s):(s); } #define R(x) x=read() inline void write(ll x) { if(x<0) { putchar('-'); x=-x; } if(x<10) { putchar(x+'0'); return; } write(x/10); putchar((x%10)+'0'); return; } inline void writeln(ll x) { write(x); putchar('\n'); return; } #define W(x) write(x),putchar(' ') #define Wl(x) writeln(x) const int N=10005,B=35,inf=0x3f3f3f3f; int n,C,Gongx[N][B],dp[N][B]; int main() { int i,j,k; R(n); R(C); for(i=1;i<=C;i++) { int Haip=0,Xih=0,E,F,L; R(E); R(F); R(L); for(j=1;j<=F;j++) { int x=read(); Haip|=(1<<((x-E+n)%n)); } for(j=1;j<=L;j++) { int x=read(); Xih|=(1<<((x-E+n)%n)); } for(j=0;j<32;j++) { Gongx[E][j]+=(((j^31)&Haip)||(Xih&j))?1:0; } } int ans=0; for(i=0;i<16;i++) { for(j=0;j<32;j++) dp[0][j]=-inf; dp[0][i<<1]=dp[0][(i<<1)|1]=0; for(j=1;j<=n;j++) { for(k=0;k<32;k++) { dp[j][k]=max(dp[j-1][(k&15)<<1],dp[j-1][((k&15)<<1)|1])+Gongx[j][k]; } } ans=max(ans,max(dp[n][i<<1],dp[n][(i<<1)|1])); } Wl(ans); return 0; } /* input 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 output 5 input 12 7 1 1 1 1 5 5 1 1 5 7 5 0 3 5 7 9 7 1 1 7 9 9 1 1 9 11 9 3 0 9 11 1 11 1 1 11 1 output 6 */