zoukankan      html  css  js  c++  java
  • 木棍加工 [搜索]

    题目大意

    有很多根等长木棍,现将他们随机砍断,已知砍断后的每一节小木棍的长度,求原木棍可能的最小长度。
    

    思路

    易知原木棍的长度一定大于砍断的最大木棍长度,数据小,可以枚举原始木棍的长度len:最大小木棍长度val~小木棍长度之和sum
    显然len能整除sum,原木棍的数量cnt=sum/len.
    对于枚举的每个长度进行搜索,状态设计为stk(已经拼好的原始木棍数量),snow(正在拼的原始木棍长度),last(当前要使用的小木棍);
    递归边界:stk==cnt+1,即所有原始木棍已经拼好.
    考虑剪枝:
    1.木棍顺序等效性:从大到小取小木棍;
    2.空木棍的等效性:对于一根新的空木棍,如果拼入的第一根木棍就萎了,那就直接回溯;
    3.等长木棍等效性:对于当前原始木棍,如果某个木棍的长度拼进去是萎的,那么相同长度的木棍也不要拼进去了;
    4.贪心:对于当前原始木棍,拼入一根木棍后如果刚好拼满,而且在之后的过程中萎了,那么也可以直接回溯。(“再用一根木根恰好拼完”比“再用几根拼完”更优)。
    想清楚了就身心愉快 想不清楚就多想几遍

    Code

    #include <cstring>
    #include <algorithm>
    #include <cstdio>
    #define ll long long
    using namespace std;
    inline int read(){
    	int x=0,f=1;char c=getchar();
    	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    	while (c>='0'&&c<='9') {x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    	return x*f;
    }
    const int maxn(100);
    int a[maxn],v[maxn],n,m,len,cnt,sum,val;
    bool dfs(int stk,int snow,int last){
    	if (stk==cnt+1) return 1;
    	if (snow==len) return dfs(stk+1,0,1);
    	int fail=0;
    	for (int i(last);i<=m;++i)
    		if (!v[i]&&snow+a[i]<=len&&fail!=a[i]){
    			v[i]=1;
    			if (dfs(stk,snow+a[i],i+1)) return 1;
    			fail=a[i];
    			v[i]=0;
    			if (snow==0||snow+a[i]==len) return 0;
    		}
    	return 0;
    }
    
    bool cmp(int x,int y){return x>y;}
    
    void init(){
    	sum=0,val=0,m=0;
    	for (int i(1);i<=n;++i){
    		if (a[i]>50) continue;//它这个题目数据是萎的,可能大于50,是出题人的锅
    		a[++m]=read(),sum+=a[m],val=max(val,a[m]);
    	}
            sort(a+1,a+m+1,cmp);
    }
    
    void doit(){
    	for (len=val;len<=sum;++len){
    		if (sum%len) continue;
    		cnt=sum/len;
    		memset(v,0,sizeof v);
    		if (dfs(1,0,1)) {printf("%d
    ",len);break;}
    	}
    }
    
    signed main(){
    	n=read();
    	while (n!=0){
    		init();
    		doit();
    		n=read();
    	}
    	return 0; 
    }
    
    
  • 相关阅读:
    easyui好例子,值得借鉴
    DDL 和DML 区别
    兼容IE的文字提示
    搭代理
    美国服务器
    跟随滚动条滚动
    JS Array对象
    JS 内置对象 String对象
    JS 对象
    JS 二维数组
  • 原文地址:https://www.cnblogs.com/cancers/p/12018978.html
Copyright © 2011-2022 走看看