小木棍 爆搜剪枝

Posted santiego

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了小木棍 爆搜剪枝相关的知识,希望对你有一定的参考价值。

小木棍 爆搜剪枝

看了题解,用一个桶记录小木棍(很是机智,反正\(N\le50\)),然后就是爆搜剪枝了。

主要是注意一个优化思想:每次拼一个木棍时,一定先用大的去填再用小的去补。

递减遍历桶和下面这个最重要的剪枝都是这个优化思想

if(sum+i==per||sum==0) break;

连用大刚好填满这种最优方法都无法拼出,那更不用说先用小的去拼这种方法了。

#include <cstdio>
#include <cstdlib>
#define MAX(A,B) ((A)>(B)?(A):(B))
#define MIN(A,B) ((A)<(B)?(A):(B))
using namespace std;
int n,cnt[55];
int mx=0,mi=75;
void solve(int num, int sum, int per, int s)
    if(num==0)
        printf("%d\n", per);
        exit(0);
    
    if(sum==per)
        solve(num-1, 0, per, mx);
        return;
    
    for(register int i=s;i>=mi;--i)
        if(cnt[i]==0||i+sum>per) continue;
        --cnt[i];
        solve(num, sum+i, per, i);
        ++cnt[i];
        if(sum+i==per||sum==0) break;
    

int temp,all;
int main()
    scanf("%d", &n);
    for(int i=1;i<=n;++i)
        scanf("%d", &temp);
        ++cnt[temp];
        all+=temp;
        mx=MAX(mx, temp);
        mi=MIN(mi, temp);
    
    for(int i=mx;i<=all/2;++i)
        if(all%i!=0) continue;
        solve(all/i, 0, i, mx);
    
    printf("%d\n", all);
    return 0;

以上是关于小木棍 爆搜剪枝的主要内容,如果未能解决你的问题,请参考以下文章

3498 小木棍

小木棍(暴搜)

poj1011(DFS+剪枝)

UVa307 Sticks (DFS+剪枝)

165. 小猫爬山爆搜+剪枝

数组切分 (蓝桥杯)爆搜,剪枝 JAVA