用1分割开的连续的2中间,只有一个人能是happy的,那么我们可以计算出f[i],用二进制表示要让i happy,需要牺牲哪些人他们不能是happy的,于是又一种随机化的做法,就是随机选取的人的顺序,然后从前到后判断当前人是否还没有被牺牲,没有被牺牲直接选。网上题解有人500次随机都过了,不过我还是学习了一个按时间写法
#include<bits/stdc++.h>
#define maxl 47
using namespace std;
int n,m,tot=0,ans;
int a[maxl];
long long f[maxl];
string s;
map<string,int> mp;
inline void prework()
{
scanf("%d%d",&n,&m);
int opt;long long cur;
for(int i=1;i<=n;i++)
{
cur=0;
while(i<=n)
{
scanf("%d",&opt);
if(opt==1)
break;
cin>>s;
if(!mp.count(s))
mp[s]=tot++;
cur|=1ll<<mp[s];
i++;
}
for(int j=1;j<=m;j++)
if((1ll<<(j-1))&cur)
f[j]|=cur;
}
}
inline void mainwork()
{
for(int i=1;i<=m;i++)
a[i]=i;
int sum;
long long cur;
while(1.0*clock()/CLOCKS_PER_SEC<1.75)
{
random_shuffle(a+1,a+1+m);
cur=0;sum=0;
for(int i=1;i<=m && cur!=(1ll<<m)-1;i++)
if((cur&(1ll<<(a[i]-1)))==0)
cur|=f[a[i]],sum++;
if(sum>ans)
ans=sum;
}
}
inline void print()
{
printf("%d",ans);
}
int main()
{
prework();
mainwork();
print();
return 0;
}