http://poj.org/problem?id=1321

(1) 和八皇后问题本质时一样的,简单的dfs 。

(2)写时没有处理好标记问题(最重要的就是标记)。第一次用了数组 mark[10][10] 做标记,由于没有处理好,WA很多次。

   第二次写时,将标技术组定位 mark[10] 。其实就是这样简洁罢了。

(3)注意 dp 时是按行进行的,如果有一行没有取到元素,就无法继续 dp ,所以要单独处理。

具体代码:

View Code
#include<stdio.h>
#include<string.h>
using namespace std;
char map[10][10];
bool mark[10];
int ans;
int n, m;
void dfs(int k, int num)
{
    int i, j;
    if(num==m) {ans++; return;}
    if(k>n) return;
    for(j=1;j<=n;j++)
        if(map[k][j]=='#'&&!mark[j])
        {
            mark[j]=1;
            dfs(k+1, num+1);
            mark[j]=0;
        }
    dfs(k+1, num);
    return;
}
int main()
{
    int i, j;
    while(scanf("%d%d", &n, &m)!=EOF)
    {
        if(n==-1&&m==-1) break;
        memset(mark, 0, sizeof(mark));
        ans=0;
        for(i=1;i<=n;i++)
            scanf("%s", map[i]+1);
        dfs(1,0);
        printf("%d\n", ans);
    }
    return 0;
}

较繁的代码:

View Code
#include<stdio.h>
#include<string.h>
using namespace std;
char map[10][10];
bool mark[10][10];
int ans;
int n, m;
void dfs(int k, int num)
{
    int i, j;
    if(num==m) {ans++; return;}
    if(k>n) return;
    for(j=1;j<=n;j++)
        if(map[k][j]=='#')
        {
            int flag=0;
            for(i=1;i<k;i++)
                if(mark[i][j]) {flag=1; break;}
            if(flag) continue;
            mark[k][j]=1;
            dfs(k+1, num+1);
            mark[k][j]=0;
        }
    dfs(k+1, num);
    return;
}
int main()
{
    int i, j;
    while(scanf("%d%d", &n, &m)!=EOF)
    {
        if(n==-1&&m==-1) break;
        memset(mark, 0, sizeof(mark));
        ans=0;
        for(i=1;i<=n;i++)
            scanf("%s", map[i]+1);
        dfs(1,0);
        printf("%d\n", ans);
    }
    return 0;
}