首页 > 其他分享 >[AcWing 167] 木棒

[AcWing 167] 木棒

时间:2022-08-24 00:12:34浏览次数:72  
标签:木棒 sum len int 当前 木棍 167 AcWing

image
image

DFS 剪枝


点击查看代码
#include<bits/stdc++.h>

using namespace std;

typedef long long LL;

const int N = 1e6 + 10;

int n;
int w[N];
int sum, len;
bool st[N];

bool dfs(int u, int s, int start)
{
    if (u * len == sum)
        return true;
    if (s == len)
        return dfs(u + 1, 0, 0);
    // 排除等效冗余 按照组合数枚举
    for (int i = start; i < n; i ++) {
        // 可行性剪枝
        if (st[i] || s + w[i] > len)
            continue;
        st[i] = true;
        if (dfs(u, s + w[i], i + 1))
            return true;
        st[i] = false;
        // 排除等效冗余 放到头尾失败则失败
        if (!s || s + w[i] == len)
            return false;
        // 排除等效冗余 排除掉相同值的元素
        int j = i;
        while (j < n && w[j] == w[i])
                j ++;
        i = j - 1;
    }
    return false;
}

void solve()
{
    while (cin >> n, n) {
        memset(st, false, sizeof st);
        sum = 0;
        for (int i = 0; i < n; i ++) {
            cin >> w[i];
            sum += w[i];
        }
        // 优化搜索顺序 从大到小排序
        sort(w, w + n, greater<int>());
        len = 1;
        while (true) {
            // 可行性剪枝
            if (sum % len == 0 && dfs(0, 0, 0)) {
                cout << len << endl;
                break;
            }
            len ++;
        }
    }
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    solve();

    return 0;
}

  1. 优化搜索顺序
    从大到小排序,减少分支的数量
  2. 可行性剪枝
    只有当单个木棒的长度 \(len\) 可以整除总长度 \(sum\) 时,才进行 \(DFS\)
  3. 排除等效冗余
    ① 按照组合数枚举
    ② 如果当前木棍加到当前棒中失败,则直接略过后面所有长度等于当前木棍的木棍
    ③ 如果当前木棍在当前棒的头部失败,则一定失败
    证明:假设存在一种方案,将当前木棍放到后续的棒中成功,则通过调整法,先将木棍调整到该木棍所在棒的最前面,再交换两木棒的位置,这样就把木棒调整到如果这句话的位置,出现矛盾
    ④ 如果当前木棍在当前棒的尾部失败,则一定失败
    证明:假设存在一种方案,将当前木棍放到后续的棒中成功,由于木棒的长度都相同,那么即使不把当前木棍拼接到当前木棒,最后当前木棒拼接的长度总和还是等于当前木棍,那么通过把这一段的木棍和当前木棍调整,就会出现矛盾

标签:木棒,sum,len,int,当前,木棍,167,AcWing
From: https://www.cnblogs.com/wKingYu/p/16618331.html

相关文章

  • 开坑之Acwing算法进阶课题单
    当初五折的时候冲动消费买下的,现在看题单内容挺丰富的,适合打基础,也适合存板子,于是回来刷.(不一定看视频)需要学习的知识点包括1图论1.1网络流1.1.1最大流1.1.1.1算......
  • AcWing算法基础课---第一讲基础算法---05位运算
    ###整数n的二进制数的第k位数```n>>k&1```###lowbit运算```lowbit(x)x&(~x+1)=x&(-x)```###AcWing801.二进制中1的个数```#include<iostream>usingn......
  • AcWing算法基础课---第一讲基础算法---03前缀和与差分
    前缀和思路:求l到r区间的和用前r个数减去前l-1个数.#include<iostream>usingnamespacestd;constintN=100010;inta[N],s[N];intmain(){intn,m;......
  • AcWing算法基础课---第一讲基础算法---02二分
    整数二分模板l=mid这个模板mid需要+1intbsearch_1(intl,intr){while(l<r){intmid=l+r>>1;if(check(mid))r=mid;//check()判断mid是否满足性......
  • AcWing算法基础课---第一讲基础算法---01排序
    快速排序步骤确定分界点:q[l],q[(l+r)/2],q[r],随机调整区间递归处理voidquick_sort(intq[],intl,intr){if(l>=r)return;//递归结束条件......
  • CodeForces-1671E Preorder
    Preorder树型dp+思维\(dp[i]\)表示以\(i\)为根的子树通过变换有多少种不同的先序遍历状态转移方程:当左右子树不同,两个子树交换位置之后,没有重复的出现:\(dp[x]......
  • 【DP 记录】AcWing 734. 能量石
    传送门给你几个物品,每种选一次,求最大价值,首先想到01背包,但是我们遇到了一个问题:普通的01背包在选择物品时是不讲求顺序的,但在这道题中,物品的选择是有顺序的(即对最优......
  • [AcWing 166] 数独
    DFS+剪枝+位运算优化点击查看代码#include<bits/stdc++.h>usingnamespacestd;typedeflonglongLL;constintN=9,M=1<<N;intones[M];//on......
  • acwing204.表达整数的奇怪方式(中国剩余定理)
    中国剩余定理中国剩余定理百度百科不定方程\(ax+by=gcd(a,b)\)的解先用扩展欧几里得算法求得不定方程的一组特解:\(x_0,y_0\)则不定方程的通解为\[\left\{\begin......
  • [AcWing 165] 小猫爬山
    DFS剪枝点击查看代码#include<bits/stdc++.h>usingnamespacestd;typedeflonglongLL;constintN=50+10;intn,m;intw[N];intsum[N];//每组......