小木棍

搜索+优化 AAA ——————————————————————————————————————————

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=70;
int n,a[N],cnt,maxn,goal;
bool cmp(int x,int y){return x>y;}
bool use[N];
inline void dfs(int ans,int num,int pre){//当前拼成的长度,目标大木棍的数目,当前搜索小木棍的位置 
    if(num==0){printf("%d\n",goal); exit(0);} 
    if(maxn-ans<a[cnt])return;    //"2"如果剩余长度小于最小长度return
    if(ans==goal)
    {
        dfs(0,num-1,1); //如果失败return
        return;
    }    
    for(register int i=pre;i<=cnt;i++)//"1"
        if(!use[i] && ans+a[i]<=goal){
            use[i]=1;
            dfs(ans+a[i],num,i+1);
            use[i]=0; 
            while(a[i]==a[i+1])i++;//"3"17,9,9,9,9,8,5,2……如果当前最长小棒为17,它与第一个9组合之后dfs发现不能拼成len
            if(ans+a[i]==goal || ans==0) return;   
        }
        //当前长度ans+a[i]为目标长度,但是后面失败了,说明该长度不合法
        //解释:如果合法,ans+a'[i]为目标长度,但是a[i]放到后面也一定会失败,因为枚举是从大到小
        //ans=0 ,a[i]为拼凑goal长度的第一根木棒,当前或者后面失败了,说明该长度不合法
        //解释:如果当前失败了a[i]+len凑不成goal,就是a[i]+后面的木棍怎么拼都拼不出goal,因此该长度不合法
        //如果当前成功了a[i]+len凑成goal,但后面失败了,说明将a[i]换成其他几个木棒,a[i]放后面也一定会失败,原因和刚才一样,因为枚举是从大到小
        //ans=0还可以理解为ans+a[i]=goal的下一步就是ans=0了,因此等同于ans+a[i]=goal
    return ; 
}
int main(){
    scanf("%d",&n);
    for(register int i=1;i<=n;i++){
        int x;
        scanf("%d",&x);
        if(x<=50){a[++cnt]=x; maxn+=a[cnt];}
    }
    sort(a+1,a+cnt+1,cmp);   
    goal=a[1];
    while(goal<=maxn/2)//"0"  
    {
        if(maxn%goal==0) 
            dfs(0,maxn/goal,1);//当前拼成的长度,目标大木棍数目,上一个数的位置
        goal++;    
    }
    printf("%d\n",maxn);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值