pku 2531 Network Saboteur DFS
http://poj.org/problem?id=2531
就是和原来的奶牛翻碗问题,翻黑白棋问题,开门问题属于一类题目,对于每一点只有两种状态,要么属于A要么属于DFS枚举出所有的状态即可。。才开始自己按自己的习惯写的DFS1469ms
最后看了看别人的优化到了375ms。。。就是在处理求和时的优化了。。
我的代码:
View Code
#include <iostream> #include <cstring> #include <cstdio> #define maxn 23 using namespace std; bool vt[maxn]; int n,ans; int map[maxn][maxn]; void dfs(int num) { int i,j; if (num == n) { int sum = 0; for (i = 0; i < n; ++i) { if (vt[i]) { for (j = 0; j < n; ++j) { if (!vt[j]) sum += map[i][j]; } } } if (sum > ans) ans = sum; return ; } for (int k = 0; k < 2; ++k) { if (k == 1)//代表属于A { vt[num + 1] = true; dfs(num + 1); vt[num + 1] = false; } else if (k == 0)//代表不属于A { dfs(num + 1); } } } int main() { //freopen("in.txt","r",stdin); int i,j; scanf("%d",&n); for (i = 0; i < n; ++i) { for (j = 0; j < n; ++j) { scanf("%d",&map[i][j]); } } ans = -99999999; memset(vt,false,sizeof(vt)); for (i = 0; i < 2; ++i) { if (i == 1) { vt[0] = true; dfs(1); vt[0] = false; } else if (i == 0) { dfs(1); } } printf("%d\n",ans); return 0; }
优化后代码:
View Code
#include <iostream> #include <cstring> #include <cstdio> #define maxn 24 using namespace std; bool vt[maxn]; int map[maxn][maxn]; int n,ans; void dfs(int num,int sum) { int i; if (num == n) { if (sum > ans) ans = sum; return ; } vt[num] = false; int m = 0; //每次当这个点不属于A要加上他与属于A的距离 for (i = 0; i <= num; ++i) { if (vt[i]) m += map[num][i]; } dfs(num + 1,sum + m); vt[num] = true; m = 0; //每次当这个点属于A要加上他与不属于A的距离 for (i = 0; i <= num; ++i) { if (!vt[i]) m += map[num][i]; } dfs(num + 1,sum +m); } int main() { //freopen("in.txt","r",stdin); int i,j; scanf("%d",&n); for (i = 0; i < n; ++i) { for (j = 0; j < n; ++j) { scanf("%d",&map[i][j]); } } ans = -9999999; memset(vt,false,sizeof(vt)); dfs(0,0); printf("%d\n",ans); return 0; }