您的位置:首页 > 其它

uva 11795洛克人的难题(集合dp)

2015-05-09 15:46 363 查看
题意:给定一个初始武器,可以消灭编号1-i的人

每消灭一个机器人,获得其武器。

求总共可以有多少种方法消灭所有的机器人。

思路很简单,集合的动态规划,但要注意的是,由于16!会爆int,所以ans要用ll类型,之前一直wa就是因为没注意这个问题.........

上码

#include<cstdio>  
#include<cstring>  
#include<cmath>  
#include<cstdlib>  
#include<iostream>  
#include<algorithm>  
#include<vector>  
#include<map>  
#include<queue>  
#include<stack> 
#include<string>
#include<map> 
using namespace std;  
#define LL long long  
const int maxn=20;
int kill[maxn][maxn];
LL ans;
int n;
int ki[maxn];
LL d[(1<<16)+10];

LL dp(int s){
	if(d[s]!=-1) return d[s];
	if(s==(1<<n)-1) return 1;
	d[s]=0;
	int tag[maxn]={0};
	for(int i=0;i<n;i++){
		if(!(s&(1<<i))&&ki[i+1]){
			for(int k=1;k<=n;k++){
				if(!ki[k]&&kill[i+1][k]){
					tag[k]=1;
					ki[k]=1;
				} 
			}
			d[s]+=dp(s|(1<<i));
			for(int k=1;k<=n;k++) if(tag[k]) ki[k]=0;
		}
	}
	return d[s];
}
string str[maxn];
int main(){
	//freopen("input.txt","r",stdin);
	int t,kase=0;
	scanf("%d",&t);
	while(kase<t){
		memset(ki,0,sizeof(ki));
		memset(d,-1,sizeof(d));
		scanf("%d",&n);
		for(int i=0;i<=n;i++){
			cin>>str[i];
			for(int j=1;j<=n;j++) kill[i][j]=str[i][j-1]-'0';
		}
		for(int i=1;i<=n;i++) ki[i]=kill[0][i];
		
		ans=dp(0);
		printf("Case %d: %lld\n",++kase,ans);
	}
}



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: