小木棍 爆搜剪枝

小木棍 爆搜剪枝

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

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

时间: 2024-11-10 01:13:38

小木棍 爆搜剪枝的相关文章

【BZOJ-1853&amp;2393】幸运数字&amp;Cirno的完美算数教室 容斥原理 + 爆搜 + 剪枝

1853: [Scoi2010]幸运数字 Time Limit: 2 Sec  Memory Limit: 64 MBSubmit: 1817  Solved: 665[Submit][Status][Discuss] Description 在中国,很多人都把6和8视为是幸运数字!lxhgww也这样认为,于是他定义自己的“幸运号码”是十进制表示中只包含数字6和8的那些号码,比如68,666,888都是“幸运号码”!但是这种“幸运号码”总是太少了,比如在[1,100]的区间内就只有6个(6,8,

[BZOJ1193][HNOI2006]马步距离 大范围贪心小范围爆搜

1193: [HNOI2006]马步距离 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1988  Solved: 905[Submit][Status][Discuss] Description 在国际象棋和中国象棋中,马的移动规则相同,都是走"日"字,我们将这种移动方式称为马步移动.如图所示, 从标号为 0 的点出发,可以经过一步马步移动达到标号为 1 的点,经过两步马步移动达到标号为 2 的点.任给 平面上的两点 p 和 s ,它

hdu5355 思维+爆搜

pid=5355">http://acm.hdu.edu.cn/showproblem.php?pid=5355 Problem Description There are?m?soda and today is their birthday. The?1-st soda has prepared?n?cakes with size?1,2,-,n. Now?1-st soda wants to divide the cakes into?m?parts so that the total

小木棍(爆搜减枝)

题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过5050. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度. 给出每段小木棍的长度,编程帮他找出原始木棍的最小可能长度. 输入输出格式 输入格式: 共二行. 第一行为一个单独的整数N表示砍过以后的小木棍的总数,其中N≤65N≤65 (管理员注:要把超过5050的长度自觉过滤掉,坑了很多人了!) 第二行为NN个用空个隔开的正整数,表示NN根小木棍的长度. 输出格式: 一个数,表示要

8/2 multi4 E找规律+模拟,空间开小了然后一直WA。。。J爆搜check不严谨WA。。。multi3 G凸包判共线写错数组名???样例太好过.想哭jpg。

multi4 Problem E. Matrix from Arrays 题意:构造一个数组,求子矩阵前缀和. 思路:打表找规律,"发现"L为奇数时循环节为L,为偶数时循环节为2L,求相应循环节的二维前缀和然后加加减减计算一下就好. 虚伪地证明一下循环节:L为奇数时对于第x行/列开始的位置有(x  +  x+L-1)*L/2   ->     (2x+L-1)/2(为整数)*L,因此扫过L行/列也就扫过了L整数倍"(2x+L-1)/2"倍的A[0]~A[L],

爆搜解hdu1572下沙小面的(2)

#include<iostream> #include<map> #include<string> #include<cstring> #include<cstdio> #include<cstdlib> #include<cmath> #include<queue> #include<vector> #include<algorithm> using namespace std; in

有一种恐怖,叫大爆搜

到目前这个阶段,大爆搜做了好几个,有必要做一下小的总结了. 玛雅游戏:出门左转 http://www.cnblogs.com/Loser-of-Life/p/7247413.html的A 斗地主:出门右转http://www.cnblogs.com/Loser-of-Life/p/7259858.html的B 天鹅会面:出门直行http://www.cnblogs.com/Loser-of-Life/p/7295770.html的A 引水入城:链接:http://cogs.pro/cogs/pr

小木棍 (codevs 3498)题解

[问题描述] 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过100. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度. 给出每段小木棍的长度,编程帮他找出原始木棍的最小可能长度. [样例输入] 9 5 2 1 5 2 1 5 2 1 [样例输出] 6 [解题思路] 这道题的核心思想就一个字,搜……首先找到最大的那一段,原始木棍的可能长度必定>=最大的那一段木棍的长度,所以我们从最大的那一段长度开始往木棍总长度搜,将木棍排序,定义f布尔

luogu P1120 小木棍 [数据加强版]

二次联通门 : luogu P1120 小木棍 [数据加强版] /* luogu P1120 小木棍 [数据加强版] 暴搜 + 剪枝 枚举可能的长度 挨个检查答案 二分显然正确性不能保障 搜索时从最大的开始找 放上当前木棍后的长度比枚举的长度要大, 则退出 若当前的长度与当前扫到的木棍长度相同, 或是还需要的长度与枚举的长度相同,则退出 若当前的木棍不符合要求, 则后面与它长度相同的木棍都不行 */ #include <algorithm> #include <iostream>