zoukankan      html  css  js  c++  java
  • CodeForces 1105E

    题目链接

    std:meet in the middle

    首先把所有的点分成两部分,设(f_i)为前半部分在点集(i)中选出的最大独立集,(g)为在后半部分选。这个可以在(O(2^{m/2}))的时间复杂度里得到。

    然后考虑把答案合起来。在f中是从i这个集合里面选出最大独立集,那么后半部分选的集合一定不能有与i相连的边,那么就把i集合里的点的所有与后半部分相连的点标记成不能选,然后在后半部分选剩下的就好了,这些都已经预处理出来了。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<cctype>
    #include<map>
    #include<string>
    #include<iostream>
    #define qmin(x,y) (x=min(x,y))
    #define qmax(x,y) (x=max(x,y))
    using namespace std;
    
    inline char gc() {
    //	static char buf[100000],*p1,*p2;
    //	return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    	return getchar();
    }
    
    template<class T>
    int read(T &ans) {
    	ans=0;char ch=gc();T f=1;
    	while(!isdigit(ch)) {
    		if(ch==EOF) return -1;
    		if(ch=='-') f=-1;
    		ch=gc();
    	}
    	while(isdigit(ch))
    		ans=ans*10+ch-'0',ch=gc();
    	ans*=f;return 1;
    }
    
    template<class T1,class T2>
    int read(T1 &a,T2 &b) {
    	return read(a)!=EOF&&read(b)!=EOF?2:EOF;
    }
    
    template<class T1,class T2,class T3>
    int read(T1 &a,T2 &b,T3 &c) {
    	return read(a,b)!=EOF&&read(c)!=EOF?3:EOF;
    }
    
    typedef long long ll;
    const int Maxn=41;
    const int Maxm=1100000;
    const int inf=0x3f3f3f3f;
    
    bool mp[Maxn][Maxn],vis[Maxn];
    map<string,int> name;
    int f[Maxm],g[Maxm],ans,m,x,st[Maxn],top,cnt;
    int n;
    string s;
    
    signed main() {
    //	freopen("test.in","r",stdin);
    	read(n,m);memset(mp,1,sizeof(mp));
    	for(int i=1;i<=n;i++) {
    		read(x);
    		if(x==1) {
    			for(int j=1;j<=top;j++)
    				for(int k=j+1;k<=top;k++)
    					mp[st[j]][st[k]]=mp[st[k]][st[j]]=0;
    			top=0;memset(vis,0,sizeof(vis));
    		}
    		else {
    			cin>> s;
    			if(!name.count(s)) name[s]=cnt++;
    			int x=name[s];
    			if(!vis[x]) {
    				vis[x]=0;
    				st[++top]=x;
    			}
    		}
    	}
    	for(int j=1;j<=top;j++)
    		for(int k=j+1;k<=top;k++)
    			mp[st[j]][st[k]]=mp[st[k]][st[j]]=0;
    	int s1=m/2,s2=m-s1;
    	for(int i=0;i<s1;i++) f[1<<i]=1;
    	for(int i=0;i<(1<<s1);i++)
    		for(int j=0;j<s1;j++) if(!(i&(1<<j))) {
    			int flag=1;
    			for(int k=0;k<s1;k++)
    				if(i&(1<<k)) flag&=mp[j][k];
    			qmax(f[i|(1<<j)],f[i]+flag);
    		}
    	for(int i=0;i<s2;i++) g[1<<i]=1;
    	for(int i=0;i<(1<<s2);i++)
    		for(int j=0;j<s2;j++) if(!(i&(1<<j))) {
    			int flag=1;
    			for(int k=0;k<s2;k++)
    				if(i&(1<<k)) flag&=mp[j+s1][k+s1];
    			qmax(g[i|(1<<j)],g[i]+flag);
    		}
    	for(int i=0;i<(1<<s1);i++) {
    		int flag=(1<<s2)-1;
    		for(int j=0;j<s1;j++) if(i&(1<<j))
    			for(int k=0;k<s2;k++) if(flag&(1<<k)&&!mp[j][k+s1])
    				flag^=1<<k;
    		qmax(ans,f[i]+g[flag]);
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    
    
    
  • 相关阅读:
    前端-----盒子模型
    跨域
    DRF的分页
    DRF的权限和频率
    DRF 版本和认证
    DRF的视图和路由
    APIView和View的区别
    Serializers序列化组件
    RESTful
    Vuex以及axios
  • 原文地址:https://www.cnblogs.com/shanxieng/p/10296984.html
Copyright © 2011-2022 走看看