标签:dfs
4 4 2 1 1 1 2 5 5 8 0 0 1 0 1 1 2 0 2 3 3 1 3 2 4 0
8 9
链接:http://acm.hdu.edu.cn/showproblem.php?pid=4499
题意:给你一个n*m的棋盘,有q个点已经放了棋。问最多还能放多少炮。要求炮与炮之间不能互相攻击。也就是两个炮直接不能隔着炮或者隔着棋。
做法:棋盘大小最大25个格子。2^25=3*10^7。如果枚举每个状态还要判断可不可行会超时。 所以我用了dfs。每次那个位置如果没有棋,就摆上炮dfs下去,每次摆判断和正上方一排冲突不冲突,还有左边一排冲不冲突。不冲突才可以摆。 再把炮去掉dfs下去。如果没有棋,就dfs不摆炮就行了。
#pragma comment(linker, "/STACK:1024000000,1024000000") #include <stdio.h> #include <stdlib.h> #include <string.h> #include <limits.h> #include <malloc.h> #include <ctype.h> #include <math.h> #include <string> #include <iostream> #include <algorithm> using namespace std; #include <stack> #include <queue> #include <vector> #include <deque> #include <set> #include <map> int n,m,q; int mp[5][5]; int ass; int dfs(int nw,int fa) { if(nw==n*m) { return fa; } int x=nw/m; int y=nw%m; int maxx=fa; if(mp[x][y]!=1) { int flag=0; if(mp[1][0]==2&&mp[3][0]==2&&nw==20) int kk=1; for(int i=x-1;i>=0;i--) { if(flag==1&&mp[i][y]==2) flag=2; if(flag==1&&mp[i][y]==1) break; if(flag==0&&(mp[i][y]==1||mp[i][y]==2))//炮 flag=1; } int flag2=0; for(int i=y-1;i>=0;i--) { if(flag2==1&&mp[x][i]==2) flag2=2; if(flag2==1&&mp[x][i]==1) break; if(flag2==0&&(mp[x][i]==1||mp[x][i]==2))//炮 flag2=1; } if(flag!=2&&flag2!=2) { mp[x][y]=2; maxx=max(maxx,dfs(nw+1,fa+1)); mp[x][y]=0; maxx=max(maxx,dfs(nw+1,fa)); } else maxx=max(maxx,dfs(nw+1,fa)); } else maxx=max(maxx,dfs(nw+1,fa)); return maxx; } int main() { while(scanf("%d%d%d",&n,&m,&q)!=EOF) { memset(mp,0,sizeof mp); ass=0; for(int i=0;i<q;i++) { int x,y; scanf("%d%d",&x,&y); mp[x][y]=1; } printf("%d\n",dfs(0,0)); } return 0; }
标签:dfs
原文地址:http://blog.csdn.net/u013532224/article/details/45604933