http://poj.org/problem?id=1321
dfs依据的很重要的一点:当剩余行数小于剩余棋子数时就不要再搜了。
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <math.h>
#include <string.h>
#include <queue>
#include <string>
#define LL long long
#define _LL __int64
#define eps 1e-8
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 10;
int n,m;
char Map[maxn][maxn];
int vis[maxn];
int ans;
void dfs(int x,int cur)
{
if(x > m)
{
ans++;
return;
}
if(cur > n)
return;
for(int i = cur; ;i++)
{
if(n-i < m-x) //判断。当剩余行数小于剩余棋子数时跳出循环
break;
for(int j = 1; j <= n; j++)
{
if(!vis[j] && Map[i][j] == '#')
{
vis[j] = 1;
dfs(x+1,i+1);//手残把i+1写成了cur+1
vis[j] = 0;
}
}
}
}
int main()
{
while(~scanf("%d %d",&n,&m))
{
if(n == -1 && m == -1)
break;
for(int i = 1; i <= n; i++)
scanf("%s",Map[i]+1);
ans = 0;
memset(vis,0,sizeof(vis));
dfs(1,1);
printf("%d\n",ans);
}
return 0;
}