POJ-2078(dfs + 剪枝)

来源:互联网 发布:洮南幼儿带网络监控的 编辑:程序博客网 时间:2024/06/02 17:41

题目:http://poj.org/problem?id=2078

暴搜加剪枝:rotate实际上是相对的,所以第一行可以不动,而且当发现一行的和不小于当前结果时,可以立马结束本次搜索,另外,取模运算真的很慢呀。。。


#include <cstdio>#include <algorithm>using namespace std;#define INF999999999int n, matrix[7][7];int offset[7], ans;void check(){int maxsum = -INF;for(int j = 0; j < n; ++j){int sum = 0;for(int i = 0; i < n; ++i){int k = j + offset[i];sum += matrix[i][k < n ? k : k - n];}if(sum >= ans) return;maxsum = max(maxsum, sum);}ans = maxsum;}void dfs(int i){if(i == n){check();return;}int& shift = offset[i];for(shift = 0; shift < n; ++shift) dfs(i + 1);}int main(){while(scanf("%d", &n), n != -1){for(int i = 0; i < n; ++i)for(int j = 0; j < n; ++j)scanf("%d", matrix[i] + j);ans = INF;dfs(1);printf("%d\n", ans);}return 0;}

如果手动模拟递归的话,又可以优化一些:


#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define INF999999999int n, matrix[7][7];int offset[7], ans;void check(){int maxsum = -INF;for(int j = 0; j < n; ++j){int sum = 0;for(int i = 0; i < n; ++i){int k = j + offset[i];sum += matrix[i][k < n ? k : k - n];}if(sum >= ans) return;maxsum = max(maxsum, sum);}ans = maxsum;}int main(){int i, j;while(scanf("%d", &n), n != -1){for(i = 0; i < n; ++i)for(j = 0; j < n; ++j)scanf("%d", matrix[i] + j);if(n == 1){printf("%d\n", matrix[0][0]);continue;}ans = INF;memset(offset, 0, n << 2);while(!offset[0]){for(i = 0; i < n; ++i){offset[n-1] = i;check();}for(j = n-2; j > -1 && ++offset[j] == n; --j) offset[j] = 0;}printf("%d\n", ans);}return 0;}



0 0
原创粉丝点击