pku 1011 sticks 搜索+剪枝 解题报告

pku 1011 sticks 搜索+剪枝 解题报告 1、 从大到小搜索,缩小其搜索的范围。 2、 剪枝。 AC代码: #include #include #include int n, sum, len, number; int sticks[65]; bool visit[65], flag; int cmp(const void *a, const void *b) { return *(int*)b - *(int*)a; } //length为当前木棍组合的长度,num为当前组合木棍的数量 void dfs(int p, int length, int num) { int i, pre; if (num == number) //符合要求 { flag = true; } else if (length == len) //其中一条组合已经符合要求 { dfs(0, 0, num + 1); //标记当前组合木棍数量+1,再来一次搜索组合 } else { for (i = p, pre = -1; i < n; i++) { if (!visit[i] && sticks[i] != pre && sticks[i] + length <= len) { pre = sticks[i]; //剪枝1 visit[i] = true; dfs(i + 1, length + sticks[i], num); visit[i] = false; if (flag || p == 0) //剪枝2 { return; } } } } } int main() { int i; while (scanf("%d", &n) && n) { sum = 0; flag = false; for (i = 0; i < n; i++) { scanf("%d", &sticks[i]); sum += sticks[i]; } qsort(sticks, n, sizeof(sticks[0]), cmp); //从大到小排列,调整搜索的顺序,搜索范围减少 for (len = sticks[0]; len < sum; len++) { if (sum % len == 0) { number = sum / len; memset(visit, false, sizeof(visit)); dfs(0, 0, 0); if (flag) { break; } } } printf("%d/n", flag ? len : sum); } return 0; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值