DFS之剪枝与优化 AcWing 167. 木棒

DFS之剪枝与优化 AcWing 167. 木棒

原题链接

AcWing 167. 木棒

算法标签

搜索 剪枝

思路

由于不知道原始木棒的长度len,但知道每根小木棍的长度,小木棒最长的时候就是一根的时候也就是长度等于所有的小木棍的长度总和sum。所以,我们可以枚举长度len。就把查询问题转化成了判断该长度是否可行的问题。
确定长度的同时也就确定了小木棒的数量cnt为sum/len,就可以作为合法标志的判断条件:在所有的小木棍都用完的情况下拼成了cnt个长度相等的小木棒。

剪枝

在这里插入图片描述

代码

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define int long long
#define x first
#define y second
#define ump unordered_map
#define pq priority_queue
#define rep(i, a, b) for(int i=a;i<b;++i)
#define Rep(i, a, b) for(int i=a;i>b;--i)
using namespace std;
typedef pair<int, int> PII;
const int N = 70;
//int t, n, m, cnt, ans; 
int sum=0, length, n;
int w[N];
bool st[N];
inline int rd(){
   int s=0,w=1;
   char ch=getchar();
   while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
   while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
   return s*w;
}
void put(int x) {
    if(x<0) putchar('-'),x=-x;
    if(x>=10) put(x/10);
    putchar(x%10^48);
}
// 从start开始的第u根木棒 木棒长度为cur 
bool dfs(int u, int cur, int start){
    if(u*length==sum){
        return true;
    }
    // 木棒长度为length 开辟第u+1个新木棒
    if(cur==length){
        return dfs(u+1, 0, 0);
    }
    // 剪枝3-1 从start寻找符合条件的木棍
    rep(i, start, n){
    	//cur+st[i]>length 可行性剪枝
        if(st[i]||cur+st[i]>length){
            continue;
        }
        st[i]=true;
        if(dfs(u, cur+w[i], i+1)){
            return true;
        }
        st[i]=false;
        // !cur 剪枝3-3
        // cur+w[i]==length 剪枝3-4
        if(!cur||cur+w[i]==length){
            return false;
        }
        // 剪枝3-2
        int j=i;
        while(j<n&&w[i]==w[j]){
            j++;
        }
        i=j-1;
    }
    return false;
}
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	while(scanf("%lld", &n), n){
	    memset(st, 0, sizeof st);
	    sum=0;
	    rep(i, 0, n){
	        w[i]=rd();
	        sum+=w[i];
	    }
	    sort(w, w+n);
	    reverse(w, w+n);
	    length=1;
	    while(true){
	        if(sum%length==0&&dfs(0, 0, 0)){
	            printf("%lld\n", length);
	            break;
	        }
	        length++;
	    }
	}
	
	return 0;
}

参考文献
AcWing 167. 木棒(算法提高课)y总视频讲解

原创不易
转载请标明出处
如果对你有所帮助 别忘啦点赞支持哈
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飞滕人生TYF

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值