P1120 小木棍 [数据加强版]-搜索+减枝

本文探讨了一个有趣的木棍拼接问题,通过剪枝优化策略减少搜索空间,提高算法效率。文章详细介绍了四种剪枝方法,包括优化顺序、整除条件、避免重复搜索和提前终止循环,并提供了完整的C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 解题思路,搜索时从小到大枚举原木棍长度,显然(木棍最大长度≤原木棍长度≤木棍总长度),然后搜索判断情况能否可行。
  • 然后就来说说最最重要的剪枝吧:
  • 1、优化顺序,dfs判断情况时从最长的木棍枚举到最短的木棍,因为能与最长的木棍组成当前需要的长度的木棍的个数显然要比长度短的少,能减少分枝数。因为长度不超过50,于是没必要对木棍长度快排,而是直接桶排,常数小且方便判断和回溯。
  • 2、木棍个数应该为整数,所以枚举的长度应该能整除总长度。
  • 3、若当前搜索时已经使用了长度为x的木棍,则下次直接从长度为x从大到小枚举,因为显然比x长的都不可行了,否则当前就不会使用x了。
  • 4、若某次搜索拼接时,当前拼好的长度为0或当前长度加上先前枚举的长度等于需要长度,直接跳出循环,因为我们是递减枚举,显然再往后搜不能再从那些长度小的木棍中拼出当前的长度。
  • #include<bits/stdc++.h>
    using namespace std;
    #define inf 0x3f3f3f3f
    #define maxn 99
    int n,maxx,lw,sum,x,dp[maxn];
    void dfs(int num,int now,int len,int up)
    {
        if(num==0)
        {
            printf("%d\n",len);
            exit(0);
        }
        if(now==len)
        {
            dfs(num-1,0,len,maxx);
            return;
        }
        for(int i=up; i>=lw; i--)
        {
            if(now+i<=len&&dp[i]>0)
            {
                dp[i]--;
                dfs(num,now+i,len,i);
                dp[i]++;
                if(!now||now+i==len)break;
            }
        }
        return;
    }
    int main()
    {
        lw=inf;
        maxx=sum=0;
        scanf("%d",&n);
        while(n--)
        {
            scanf("%d",&x);
            if(x>50)continue;
            dp[x]++;
            lw=min(x,lw);
            maxx=max(maxx,x);
            sum+=x;
        }
        x=sum>>1;
        for(int i=maxx; i<=x; i++)
        {
            if(sum%i==0)
                dfs(sum/i,0,i,maxx);
        }
        printf("%d\n",sum);
        return 0;
    }
    

     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值