题目描述
新建的圆形动物园是亚太地区的骄傲。圆形动物园坐落于太平洋的一个小岛上,包含一大圈围栏,每个围栏里有一种动物。如下图所示:
你是动物园的公关主管。你要做的是,让每个参观动物园的游客都尽可能高兴。今天有一群小朋友来到动物园参观,你希望能让他们在动物园度过一段美好的时光。但这并不是一件容易的事?D?D有些小朋友喜欢某些动物,而有些小朋友则害怕某些动物。例如, Alex 喜欢可爱的猴子和考拉,而害怕拥有锋利牙齿的狮子。而 Polly 会因狮子有美丽的鬃毛而喜欢它,但害怕有臭味的考拉。
你可以选择将一些动物从围栏中移走以使得小朋友不会害怕。但你移走的动物也不能太多,否则留给小朋友们观赏的动物就所剩无几了。
每个小朋友站在大围栏圈的外面,可以看到连续的5个围栏。你得到了所有小朋友喜欢和害怕的动物信息。当下面两处情况之一发生时,小朋友就会高兴:
至少有一个他害怕的动物被移走;
至少有一个他喜欢的动物没被移走。
例如,考虑下图中的小朋友和动物:
假如你将围栏4和12的动物移走。Alex和Ka-Shu将很高兴,因为至少有一个他们害怕的动物被移走了。这也会使 Chaitanya 高兴,因为他喜欢的围栏6和8中的动物都保留了。但是,Polly 和 Hwan 将不高兴,因为他们看不到任何他们喜欢的动物,而他们害怕的动物都还在。这种安排方式使得三个小朋友高兴。
现在换一种方法,如果你将围栏4和6中的动物移走,Alex 和 Polly 将很高兴,因为他们害怕的动物被移走了。Chaitanya 也会高兴,虽然他喜欢的动物6被移走了,他仍可以看到围栏8里面他喜欢的动物。同样的 Hwan 也会因可以看到自己喜欢的动物12而高兴。唯一不高兴的只有 Ka-Shu。
如果你只移走围栏13中的动物,Ka-Shu 将高兴,因为有一个他害怕的动物被移走了,Alex, Polly, Chaitanya 和 Hwan 也会高兴,因为他们都可以看到至少一个他们喜欢的动物。所以有5个小朋友会高兴。这种方法使得了最多的小朋友高兴。
输入格式
输出格式
仅输出一个数,表示最多可以让多少个小朋友高兴。
样例
对于全部数据 10<=N<=1e4,1<=C<=5e4,1<=E<=N
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e4+10;
int n,c,st,Max,x,l,r;
int fear,like,warch[maxn][32],dp[maxn][32];
int main()
{
scanf("%d%d",&n,&c);
for(int i=1;i<=c;i++)
{
scanf("%d%d%d",&st,&l,&r);
fear=0,like=0;
for(int j=1;j<=l;j++)
{
int num=0;
scanf("%d",&x);
num=(x-st+n)%n;
fear|=(1<<num);//可见的围栏中害怕哪些
}
for(int j=1;j<=r;j++)
{
int num=0;
scanf("%d",&x);
num=(x-st+n)%n;
like|=(1<<num);//可见的围栏中喜欢哪些
}
for(int s=0;s<32;s++)//遍历所有情况如果某种情况符合其中一个条件就+1
{
if((s&fear)||(~s&like)) warch[st][s]++;
}
}
for(int s=0;s<32;s++)
{
memset(dp,0xcf,sizeof(dp));
dp[0][s]=0;
for(int i=1;i<=n;i++)
{
for(int j=0;j<32;j++)
{
dp[i][j]=max(dp[i-1][(j&15)<<1],dp[i-1][(j&15)<<1|1])+warch[i][j];//dp由上一个状态i-1到i看是移走高兴的人多还是不移走高兴的人多
}
}
Max=max(Max,dp[n][s]);
}
printf("%d",Max);
return 0;
}