码迷,mamicode.com
首页 > 其他好文 > 详细

小木棍 爆搜剪枝

时间:2019-08-22 00:49:52      阅读:72      评论:0      收藏:0      [点我收藏+]

标签:重要   std   pre   --   不用   can   amp   oid   class   

小木棍 爆搜剪枝

看了题解,用一个桶记录小木棍(很是机智,反正\(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;
}

小木棍 爆搜剪枝

标签:重要   std   pre   --   不用   can   amp   oid   class   

原文地址:https://www.cnblogs.com/santiego/p/11391801.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!