uva 11795洛克人的难题(集合dp)
2015-05-09 15:46
363 查看
题意:给定一个初始武器,可以消灭编号1-i的人
每消灭一个机器人,获得其武器。
求总共可以有多少种方法消灭所有的机器人。
思路很简单,集合的动态规划,但要注意的是,由于16!会爆int,所以ans要用ll类型,之前一直wa就是因为没注意这个问题.........
上码
每消灭一个机器人,获得其武器。
求总共可以有多少种方法消灭所有的机器人。
思路很简单,集合的动态规划,但要注意的是,由于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); } }
相关文章推荐
- UVALive 7721 K - 2-ME Set 集合dp,所有数的位或来表示状态。
- uva 11825 黑客的攻击 Hackers' Crackdown 集合dp+我的优化 非常好的好题
- uva10911(集合DP)
- UVa 11795 - Mega Man's Mission (集合DP 状态压缩)
- UVa 11759 洛克人的难题 状压dp
- uva - 11825(高效枚举集合dp)
- UVA11795——Mega Mans Missions(集合DP,状态压缩)
- UVA 11825 集合枚举 状态压缩 dp
- UVA1099----Sharing Chocolate----在集合上的DP
- UVa 11825 集合dp
- uva10911 - Forming Quiz Teams 集合DP
- uva 11795 - Mega Man's Mission 洛克人的难题 基础集合动态规划
- [集合DP] UVA 10651 Pebble Solitaire
- UVA1099----Sharing Chocolate----在集合上的DP
- uva 1401 dp+Trie
- UVa 437 - The Tower of Babylon(DP)
- UVA 11468 Substring(AC自动机 + dp)
- Uva 10003 Cutting Sticks (区间dp)
- UVA 11077 Find the Permutations(置换+dp)
- Uva 562-Dividing coins(DP)