首页 > 代码库 > POJ 1011 Sticks
POJ 1011 Sticks
http://poj.org/problem?id=1011
题意:
给定多根木棒的长度,要求将其重新组合成若干相等长度的木棒,求组合后木棒的最小长度
解法:
dfs + 重点剪枝
自己想到的剪枝太弱了 学习整理下看到的剪枝
具体看注释
代码: 700K 0MS
#include <iostream>#include <algorithm>#include <cstring>using namespace std;#define _ ios_base::sync_with_stdio(0);cin.tie(0)#define N 64int s[N], sn, l, n, ans;bool flag, vis[N];bool cmp(int a, int b) { return a > b;}bool dfs(int crtn, int crt, int crtl) { //在找第几根,当前下标,当前根剩余长度 if (crtn == n) { //已完成n-1根,必然能完成最后一根 return 1; } for (int i = crt; i < sn; ++i) { if (vis[i] || (i && !vis[i - 1] && s[i] == s[i - 1]) || crtl < s[i]) { //已选过||已知前一根长度相同的选不上||比剩余长度大 continue; } vis[i] = 1; if (crtl == s[i]) { //完成当前根 if (dfs(crtn + 1, 0, ans)) { //从头开始找下一根 return 1; } vis[i] = 0; return 0; //若找不到下一根,则此测试长度无解 } else { if (dfs(crtn, i + 1, crtl - s[i])) { //接着找当前根 return 1; } vis[i] = 0; if (crtl == ans) { //从头开始找一根木棍时,若从当前未标记的最长的一根无法找到解,则此测试长度无解 return 0; } } } return 0;}int main() { _; while (cin >> sn && sn) { int totl = 0; for (int i = 0; i < sn; ++i) { cin >> s[i]; totl += s[i]; } sort(s, s + sn, cmp); //降序排序 for (ans = s[0]; ans < totl; ++ans) { //从最长木棍的长度开始增加测试长度 if (totl % ans == 0) { //测试的长度可整除总长度 memset(vis, 0, sizeof(vis)); n = totl / ans; //要组的根数 if (dfs(1, 0, ans)) { break; //成功则结束循环 } } } cout << ans << endl; } return 0;}
POJ 1011 Sticks
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。