poj 1753 dfs递归组合数
来源:互联网 发布:亳州淘宝店转让网 编辑:程序博客网 时间:2024/06/01 08:59
背景:一共16个棋子,每个棋子只有翻或者不翻两种情况,共有2^16种可以直接枚举。枚举的方法是组合数:C(16,k) (k:1 to 16) 就是翻1个,2个,3个.....16个的情况。其中用到了递归求组合数的思想。这种求组合数的方法和平常的思维不一样,比如求:1,2,3,4 的组合数,平常是先求一个数的:1,2,3,4四种情况,再求两个数的:12,13,14,23,24,34六种情况,再求三个数的:123,124,234三种情况,再求四个数的1234。而这个递归是dfs的方法:求1,12,123,1234,124,134,14,2,234.....对每个数开头的枚举玩。
自己写的求n个数中所有组合数的方法:
#include<map>#include<set>#include<stack>#include<queue>#include<vector>#include<cstdio>#include<cstring>#include<cstdlib>#include<iostream>#include<algorithm>#define M 200009#define INF 100000000#define LL long long intusing namespace std;int str[M],n;void dfs(int x){ str[x]=1; for(int i=0;i < n;i++) if(str[i]) printf("%d ",i); printf("\n"); for(int i=x+1;i < n;i++) dfs(i); str[x]=0; return;}int main(void){ while(~scanf("%d",&n)){ memset(str,0,sizeof(str)); for(int i=0;i < n;i++) dfs(i); } return 0;}
输入:6输出:11 21 2 31 2 3 41 2 3 4 51 2 3 4 5 61 2 3 4 61 2 3 51 2 3 5 61 2 3 61 2 41 2 4 51 2 4 5 61 2 4 61 2 51 2 5 61 2 61 31 3 41 3 4 51 3 4 5 61 3 4 61 3 51 3 5 61 3 61 41 4 51 4 5 61 4 61 51 5 61 622 32 3 42 3 4 52 3 4 5 62 3 4 62 3 52 3 5 62 3 62 42 4 52 4 5 62 4 62 52 5 62 633 43 4 53 4 5 63 4 63 53 5 63 644 54 5 64 655 66
2.以前学的递归实现全排列的代码,竟然忘了。核心是递归思想:对于长度为n的排列它的全排列等于第一个数分别和剩下的n-1个数交换,然后加上剩下n-1个数的全排列。这样一直到,只有一个全排列是排列就是它本身。
#include<map>#include<set>#include<stack>#include<queue>#include<vector>#include<cstdio>#include<cstring>#include<cstdlib>#include<iostream>#include<algorithm>#define M 200009#define INF 100000000#define LL long long intusing namespace std;int str[M],n;void sw(int &a,int &b){ if(a != b){ //异或要特判a == b的情况,要不然就是0 a=a^b; b=a^b; a=a^b; }}void print(void){for(int i=1;i <= n;i++) printf("%d ",str[i]);printf("\n");}void permutation(int x){ if(x == n){ print();return;} for(int i=x;i <= n;i++){ sw(str[x],str[i]); permutation(x+1); sw(str[x],str[i]); } return;}int main(void){ while(~scanf("%d",&n)){ for(int i=1;i <= n;i++) str[i]=i; permutation(1); } return 0;}
本题代码:
//poj 1753#include<map>#include<set>#include<stack>#include<queue>#include<vector>#include<cstdio>#include<cstring>#include<cstdlib>#include<iostream>#include<algorithm>#define M 1009#define INF 100000000#define LL long long intusing namespace std;int str[16],ans,over,str1[16];bool check(void){ int x=0; for(int i=0;i < 16;i++) x+=str[i]; if(x == 16 || !x) return true; else return false;}void deal(int s){ str[s]=!str[s]; if(s-4 >= 0) str[s-4]=!str[s-4]; if(s+4 < 16) str[s+4]=!str[s+4]; if(s%4-1 >= 0) str[s-1]=!str[s-1]; if(s%4+1 <= 3) str[s+1]=!str[s+1];}void dfs(int s){ //for(int i=0;i < 16;i++) printf("%d ",str[i]); //printf("\n ans is : %d\n",ans); deal(s); if(check()) if(ans < over) over =ans; ans++; for(int i=s+1;i < 16;i++){ dfs(i); } ans--; deal(s); return;}int main(void){ char temp; while(~scanf("%c",&temp)){ int ci=0; str[ci++]=(temp != 'b'); for(int i=1;i <= 4;i++){ for(int j=1;j <= 4;j++){ if(i == 1 && j == 1) continue; temp=getchar(); str[ci++]=(temp != 'b'); } getchar(); } memcpy(str1,str,sizeof(str1)); over=INF; for(int i=0;i < 16;i++){ ans=0; if(check()) if(ans < over) over=ans; ans++; dfs(i); memcpy(str,str1,sizeof(str1)); } if(over < INF) printf("%d\n",over); else printf("Impossible\n"); } return 0;}
0 0
- poj 1753 dfs递归组合数
- POJ 2245 Lotto(组合数dfs)
- nyoj+求所有组合数,dfs,递归需要好好理解
- NYOJ32 组合数 【DFS】
- 组合数(dfs)
- 32 组合数【dfs】
- nyoj32 组合数【DFS】
- 组合数(DFS)
- 组合数 dfs
- 组合数(dfs)
- 组合数(dfs)
- 递归求组合数
- POJ 1753 翻棋子 (dfs+递归)。
- NYOJ-32 组合数【DFS】
- NYOJ 32 组合数 dfs
- nyoj32组合数(DFS)
- HDU 32 组合数 【DFS】
- NYOJ 组合数 32(DFS)
- opencv 中的Otsu阈值化
- 判断gif是否为动图
- 数据库第二次作业
- 苹果系统修复若干办法
- EL和JSTL的学习
- poj 1753 dfs递归组合数
- Eclipse常用设置--字体
- 关于webview的补充
- PHP格式化金钱函数
- 机器学习知识体系
- jQuery each中的break
- 针对ListView滚动条会遮挡列表中内容的解决方法
- 符号积分用的Rubi软件包(Mathematica下的Package)
- 手把手教你ARC——iOS/Mac开发ARC入门和使用