ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

AcWing 167. 木棒

2021-08-17 21:34:46  阅读:338  来源: 互联网

标签:剪枝 return 木棒 int 拼接 curlen 167 AcWing


剪枝常用策略:

  1. 优化搜索顺序:可以先搜规模小的分支。

  2. 排除等效冗余:例如对于一个组合型枚举,\(1,2,3\)与\(2,3,1\)这是一样的,所以可以排除一下。

  3. 可行性剪枝:搜索过程中及时对状态进行检查,发现分支不符合本意,即提早发现是一个死胡同,就剪掉;

  4. 最优性剪枝:如果当前代价已经超过了最优解,那么就没必要再搜了。

原题链接:AcWing 167. 木棒

剪枝:

  1. 优化搜索顺序:将树枝从大到小排序。

  2. 排除等效冗余:
    (1) 那么可以按组合型顺序枚举。
    (2) 对于当前拼接失败的小木棍长度,接下来不再拼接与其长度相同的木棍。

  3. 如果在当前原始木棍中尝试拼接第一根木棍的递归分支失败了,那么就直接返回失败,不再继续搜索,直接回溯。

  4. 如果在当前原始木棍中拼入最后一根,木棒恰好拼接完整,并且接下来拼接剩余原始木搜索失败,那么直接回溯,解释如下图。

1.png

// Problem: 木棒
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/169/
// Memory Limit: 64 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>

using namespace std;

const int N = 70;
int w[N];
bool st[N];
int n, cnt, len;

//stick:第几根木棒
//curlen:当前被拼接木棒已经拼接的长度
//last:使用的上一根木棒的下标
bool dfs(int stick, int curlen, int last) {
    //所有木棒拼接好
	if (stick > cnt) return true;
	//第stick根木棒拼接完毕,拼接下一根
	if (curlen == len) return dfs(stick + 1, 0, 1);
	
	int fail = 0;
	for (int i = last; i <= n; i++) {
		if (st[i]) continue;
		if (w[i] == fail) continue; //剪枝2.2:对于当前拼接失败的小木棍长度,接下来不再拼接与其长度相同的木棍。
		if (curlen + w[i] > len) continue; //可行性剪枝
		
		st[i] = true;
		if(dfs(stick, curlen + w[i], i + 1)) return true;
		st[i] = false;
		
		//如果拼接失败
		fail = w[i]; //记录本次用的失败的小木棒
		if (curlen == 0 || curlen + w[i] == len) return false; //剪枝:3,4
	}
	
	return false;
}

int main() {
	while (cin >> n, n) {
		int maxv = 0, sum = 0;
		for (int i = 1; i <= n; i++) {
			cin >> w[i];
			sum += w[i];
			maxv = max(maxv, w[i]);
		}
		
		sort(w + 1, w + n + 1, [&](int a, int b) {
			return a > b;
		});
		
		for (len = maxv; len <= sum; len++) {
			memset(st, false, sizeof st);
			if (sum % len) continue;
			cnt = sum / len;
			if (dfs(1, 0, 1)) break;
		}
		
		cout << len << endl;
	}
    return 0;
}

		

标签:剪枝,return,木棒,int,拼接,curlen,167,AcWing
来源: https://www.cnblogs.com/ZhengLijie/p/15154271.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有