首页 > 其他 > 详细

ZOJ3305Get Sauce 状压DP,

时间:2015-02-04 23:28:46      阅读:488      评论:0      收藏:0      [点我收藏+]

状压DP的题目留个纪念,首先题意一开始读错了,搞了好久,然后弄好了,觉得DFS可以,最后超时,修改了很久还是超时,没办法看了一下n的范围,然后觉得状压可以,但是没有直接推出来,就记忆化搜索了一下,可是一直错,莫名奇妙,然后没办法看了一下题解,发现了下面这个比较好的方法,然后按照这个方程去推,然后敲,也是WA了好多把,写的太搓了,没人家的清楚明了,唉~也算是给自己留个纪念,状压一直做的都不太好~唉~还好理解了,

参考了  http://blog.csdn.net/nash142857/article/details/7968554
还有http://linest.iteye.com/blog/1175648
这两篇一起看了 了解了,也知道自己记忆化搜索错在哪里了,改了也A掉了


int n,m;

int dp[(1<<16) + 1];

void init() {
	memset(dp,-1,sizeof(dp));
}

bool input() {
	while(cin>>n>>m) {
		return false;
	}
	return true;
}

void cal() {
	int k;
	int q = m;
	int ss = (1<<n) - 1;
	while(q--) {
		int k;
		scanf("%d",&k);
		int s = 0;
		for(int i=0;i<k;i++) {
			int x;
			scanf("%d",&x);
			s |= (1<<(x - 1));
		}
		int now = ss^s;//并集减去交集,其实以1<<16为全集的,所以相当于补集
		dp[s] = max(dp[s],1);//加边界
		for(int i=now;i != 0;i = (i - 1)&now) {//对于补集进行枚举,然后跟原来的集合取交集
			if(dp[i] != -1)
				dp[s|i] = max(dp[s|i],dp[i] + 1);
		}
	}
	int ans = -1;
	for(int i=0;i<(1<<n);i++)
		ans = max(dp[i],ans);
	if(ans == -1)ans = 0;
	cout<<ans<<endl;
}

void output() {

}

int main() {
	while(true) {
		init();
		if(input())return 0;
		cal();
		output();
	}
	return 0;
}


ZOJ3305Get Sauce 状压DP,

原文:http://blog.csdn.net/yitiaodacaidog/article/details/43496473

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!