CodeChef Mike and Stamps

写了我1小时,看到m<=20就知道状态压缩,开始的时候想岔了,dp[1<<20][20000] 超内存,用map<int,int> dp[1<<20] 写。花了半小时还错的。

灵光一闪,有共同的不就是互斥嘛!先两两判互斥,再状态压缩判是否状态互斥。状态位的个数就是答案。

#include<iostream>
#include<cstdio>
#include<string.h>
using namespace std;

const int MAX=1<<20;
int mp[21][20001],n,m;
int a[21][21],num[MAX],dp[MAX];
void init(){
	num[0]=0;
	for(int i=1;i<MAX;i++)
		num[i]=num[i-(i&-i)]+1;
}
int ok(int state){//判断该状态是否能存在
	int last=state&-state,t;
	if(dp[state-last]==0) return 0;
	last=-1,t=0;
	while(state){
		if(state&1){
			if(last==-1)
				last=t;
			else{
				if(a[t][last]==1)
					return 0;
			}
		}
		t++;
		state>>=1;
	}
	return 1;
}
int main(){
	int k,t;
	init();
	while(cin>>n>>m){
		memset(mp,0,sizeof mp);
		for(int i=0;i<m;i++){
			scanf("%d",&k);
			for(int j=0;j<k;j++)
				scanf("%d",&t),mp[i][t]=1;
		}
		memset(a,0,sizeof a);
		for(int i=0;i<m;i++){//O(m*m*n) 0.1s 
			for(int j=i+1;j<m;j++)
				for(int k=1;k<=n;k++)
					if(mp[i][k]&&mp[j][k]){//i与j是否互斥
						a[j][i]=a[i][j]=1;break;
					}
		}
		memset(dp,0,sizeof dp);
		int mx=1<<m,ans=0;
		dp[0]=1;
		for(int s=1;s<mx;s++){//该状态是否能存在
			if(ok(s)){
				dp[s]=1;
				ans=max(ans,num[s]);
			}
		}
		printf("%d\n",ans);
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
stamps 4.1 是一个邮票收集和管理软件,它提供了方便的方式来记录和管理邮票收藏。 使用stamps 4.1,用户可以创建一个个人邮票收藏库,将自己的邮票收藏组织起来。它提供了一个直观易用的界面,让用户可以轻松添加、编辑和删除邮票记录。用户可以为每张邮票输入的详细信息,如邮票的国家、年份、面值、设计和特点等,以便更好地了解每张邮票的背景和重要性。 除了记录邮票的基本信息,stamps 4.1 还提供了一些高级功能,以便用户更好地管理邮票收藏。例如,用户可以添加自定义标签和分类来组织邮票,方便快速检索和浏览。另外,用户还可以将邮票按照不同的主题、系列或分类进行组织,以便更好地展示和分享邮票收藏。通过图片导入功能,用户可以将自己的邮票图像直接导入软件,并与邮票记录相关联,以便更直观地浏览和展示。 stamps 4.1 还提供了打印和导出功能,用户可以打印自己的邮票收藏清单,或者导出邮票记录到Excel或其他文件格式中,以便与他人分享或备份。此外,软件还自带了一个内置的搜索功能,用户可以根据关键词快速搜索某张特定的邮票,方便用户在大规模邮票收藏中迅速定位。 总而言之,stamps 4.1 是一个实用且功能强大的邮票收集和管理软件,它可帮助用户轻松组织、浏览和管理自己的邮票收藏,以更好地了解和欣赏自己的邮票收藏。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值