1 条题解

  • 1
    @ 2024-9-13 20:08:17

    深搜的剪枝优化

    #include<bits/stdc++.h>
    #define ULL unsigned long long
    #define LL long long
    #define PII pair<int,int>
    using namespace std;
    const int N = 1e6 + 10,M = 2 * 1e4 + 10,inf = 0x3f3f3f3f;
    
    int n,sum; 
    int length; //单个木棍的长度
    int a[110]; 
    bool st[119]; //标记数组
    bool dfs(int start,int cnt,int u) 
        /*
        start:
        表示开始坐标,便于我们搜索时不会搜到冗余的数,
        比如1 2 3 和 1 3 2拼成的木棍本质上相同
        cnt:
        表示当前拼成木棍的和
        u:
        表示正在拼第几根木棍
        */
    {
        if(u * length == sum) return true; 
        //如果拼的几根木棍的积恰好等于总长度返回true
    
        if(cnt == length) return dfs(0,0,u+1);
        //当前木棍已拼成,继续下一根木棍
        for(int i = start; i < n; i++)
        {
            if(st[i]) continue; //被用过叉出去
            if(cnt + a[i] > length) continue; 
            //当前长度加上这个木棒的长度大于了单根限制长度叉出去
    
            st[i] = 1; //标记为已用过
            if(dfs(i+1,cnt + a[i], u)) return true; 
            //加上这个木棒后继续拼这一根
            st[i] = 0; //回溯
    
            if(!cnt) return false; 
            // 剪枝: 如果连第一根木棍都没放下,直接返回false
            
            if(cnt + a[i] == sum) return false;
            // 剪枝: 如果已经到了最后一根木棒还没拼成,返回false
    
            //剪枝: 如果这一根没有被放进当前木棍中,则后面跟这个木棒长度相等的木棒也可以跳过
            int j = i;
            while(j < n && a[j]==a[i]) j++;
            i = j - 1;
        }
        return false; //没找到返回false
    }
    int main()
    {
        ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
        cin>>n;
        for(int i=0;i<n;i++)
        {
            cin>>a[i];
            sum+=a[i]; //求出木棍的总长度
        }
    
        sort(a,a+n,greater<int>()); //从大到小排序,最优策略剪枝
    
        length = a[n-1]; //从最短的木棍开始找
        while (true) //类似于迭代加深,一个长度一个长度的搜索
        {
            if(sum % length == 0 && dfs(0,0,0)) 
            //能被整除才能找吧,不能整除还怎么平均分
            {
                cout<<length<<endl;
                break;
            }
            length++;
        }
        return 0;
    }
    
    • 1

    信息

    ID
    1376
    时间
    1000ms
    内存
    128MiB
    难度
    10
    标签
    (无)
    递交数
    1
    已通过
    1
    上传者