题目链接

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\n",ans);
return 0;
}

CodeForces 1105E的更多相关文章

  1. 【Codeforces 1105E】Helping Hiasat

    Codeforces 1105 E 题意:给你m个事件,每个事件可能是以下两种之一: \(1\),代表此时可以更改用户名 \(2\) \(s\),代表\(s\)来查看是否用户名与其名字相符 一共有\( ...

  2. CodeForces 1105E Helping Hiasat 最大独立集

    Helping Hiasat 题解: 如果我们把连续的2出现的人都相互连边的话, 题目就是问最大独立集的答案是多少. 求最大独立集可以将图变成反图, 然后求最大团. 代码: #include<b ...

  3. Codeforces 1105E 最大独立集 状态DP 中途相遇法

    题意:你有一个字符串, 有两种操作,一种是改变字符串,一种是某个用户询问这个字符串,如果一个用户每次查询字符串的时候都是他的用户名,他就会高兴.问最多有多少个用户会高兴? 题意:容易发现,在两个1操作 ...

  4. python爬虫学习(5) —— 扒一下codeforces题面

    上一次我们拿学校的URP做了个小小的demo.... 其实我们还可以把每个学生的证件照爬下来做成一个证件照校花校草评比 另外也可以写一个物理实验自动选课... 但是出于多种原因,,还是绕开这些敏感话题 ...

  5. 【Codeforces 738D】Sea Battle(贪心)

    http://codeforces.com/contest/738/problem/D Galya is playing one-dimensional Sea Battle on a 1 × n g ...

  6. 【Codeforces 738C】Road to Cinema

    http://codeforces.com/contest/738/problem/C Vasya is currently at a car rental service, and he wants ...

  7. 【Codeforces 738A】Interview with Oleg

    http://codeforces.com/contest/738/problem/A Polycarp has interviewed Oleg and has written the interv ...

  8. CodeForces - 662A Gambling Nim

    http://codeforces.com/problemset/problem/662/A 题目大意: 给定n(n <= 500000)张卡片,每张卡片的两个面都写有数字,每个面都有0.5的概 ...

  9. CodeForces - 274B Zero Tree

    http://codeforces.com/problemset/problem/274/B 题目大意: 给定你一颗树,每个点上有权值. 现在你每次取出这颗树的一颗子树(即点集和边集均是原图的子集的连 ...

随机推荐

  1. 常用的windows注册表大全

    目录 使系统没有“运行”选项                        1让操作系统无“关闭系统” 选项                    2让操作系统无“注销”选项              ...

  2. dedecms建的网站如何去掉/index.html

    DEDECMS建立的网站,www.abc.com/index.html和www.abc.com两个都可以访问,而且两个页面都是一样的,这样就会造成重复页面,对搜索引擎不友好,那么怎么去掉index.h ...

  3. android studio 1

    1.继承activity类的时候,重写父类 @Override   //伪代码 ,代表如果不是重写父类的方法,该地方会报错 protected void onCreate( Bundle savedI ...

  4. Python3学习之路~2.2 简单的购物车程序

    程序:购物车程序 需求:启动程序后,让用户输入工资,然后打印商品列表允许用户根据商品编号购买商品用户选择商品后,检测余额是否够,够就直接扣款,不够就提醒 可随时退出,退出时,打印已购买商品和余额 代码 ...

  5. 下载google play上最新版的apk

    注意,是下载最新版的方法,不是像很多网站下的是旧版本 http://techapple.net/2014/09/3-websites-directly-download-apk-google-play ...

  6. Keras 源码分析

    . │ activations.py │ callbacks.py │ constraints.py │ initializations.py │ metrics.py │ models.py │ o ...

  7. Python常用函数及说明

    原文地址:博客园  CSDN 基本定制型C.__init__(self[, arg1, ...]) 构造器(带一些可选的参数)C.__new__(self[, arg1, ...]) 构造器(带一些可 ...

  8. iOS 第三方框架-MJRefresh

    MJRefresh是一款非常好用的上拉下拉第三方库,使用也很简单.github地址: https://github.com/CoderMJLee/MJRefresh . 下拉刷新 官方给过来的例子很简 ...

  9. Django初级手册4-表单与通用视图

    表单的编写 1. detail.html模版的编写 <h1>{{ poll.question }}</h1> {% if error_message %}<p>&l ...

  10. ExtJs中XTemplate使用(转)

    转自http://www.studyofnet.com/news/408.html 本文导读:XTemplate是Ext.Template扩展的新类,它支持高级功能的模板类,如自动数组输出.条件判断. ...