hdu1455 Sticks 深搜 强剪枝

Sticks

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 6035    Accepted Submission(s): 1704

Problem Description

George took sticks of the same length and cut them randomly until all parts became at most 50 units long. Now he wants to return sticks to the original state, but he forgot how many sticks he had originally and how long they were
originally. Please help him and design a program which computes the smallest possible original length of those sticks. All lengths expressed in units are integers greater than zero.

Input

The input contains blocks of 2 lines. The first line contains the number of sticks parts after cutting, there are at most 64 sticks. The second line contains the lengths of those parts separated by the space. The last line of the
file contains zero.

Output

The output file contains the smallest possible length of original sticks, one per line.

Sample Input

9
5 2 1 5 2 1 5 2 1
4
1 2 3 4
0

Sample Output

6
5
题意:给多组数据,每组数据代表一些小木棍,能否将它们全部用完组成(尽量)多个相同长度的长棍,并输出长棍的长度
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int ss,t,d,m;
int q[99];
int vis[99];
int cmp(int a,int b)
{
    return a>b;
}
void dfs(int k,int length,int num)    //  k是搜到第几根棍子   length是当前棍子长度  num是已拼好的棍子数
{
    if(t==1)
        return;
    if(num==ss)
    {
        t=1;
        return ;
    }
    if(length==d)
    {
        dfs(0,0,num+1);   //拼好的棍子加1
         if(t==1)
            return;
    }
    for(int i=k; i<m; i++)
    {
        if(vis[i]==0&&length+q[i]<=d)    //剪枝2
        {
            vis[i]=1;
            dfs(i+1,length+q[i],num);
            vis[i]=0;
            if(d-length==q[i])            //剪枝3 满足当前拼好的长棍 但不满足之后的长棍 也不用继续搜了
                return;
            if(length==0)                //剪枝4 最重要的 不写 直接TLE  当递归回来前面长棍子没用到的话 之后也就用不到了
                return;
            if(q[i]==q[i+1])               //剪枝5 相同的棍子 都拼不好 直接跳过
            i++;
        }
    }
}
int main()
{
    int i;
    int s;
    int max1;
    while(~scanf("%d",&m))
    {

        if(m==0)
            break;
        s=0;
        t=0;
        for(i=0; i<m; i++)
        {
            scanf("%d",&q[i]);
            s=s+q[i];
        }
        sort(q,q+m,cmp);        //按从大到小排序
        max1=q[0];
        for(i=max1; i<s; i++)    //应从最长那根的长度开始枚举 否则WA
        {
            if(s%i==0)             //剪枝1:木棍要全部用完 而且多个长木棍要长度相同
            {
                memset(vis,0,sizeof(vis));
                ss=s/i;
                d=i;
                dfs(0,0,0);
            }
            if(t==1)
                break;
        }
        printf("%d\n",i);
    }
    return 0;
}

hdu1455 Sticks 深搜 强剪枝,布布扣,bubuko.com

时间: 2024-10-05 19:30:30

hdu1455 Sticks 深搜 强剪枝的相关文章

【深搜加剪枝五】HDU 1010 Tempter of the Bone

Tempter of the BoneTime Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 64326    Accepted Submission(s): 17567 Problem Description The doggie found a bone in an ancient maze, which fascinated him a l

hdu 4848 Wow! Such Conquering! (暴搜+强剪枝)

Wow! Such Conquering! Time Limit: 15000/8000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 0    Accepted Submission(s): 0 Problem Description There are n Doge Planets in the Doge Space. The conqueror of Doge Space

一本通例题埃及分数—题解&amp;&amp;深搜的剪枝技巧总结

一.简述: 众所周知,深搜(深度优先搜索)的时间复杂度在不加任何优化的情况下是非常慢的,一般都是指数级别的时间复杂度,在题目严格的时间限制下难以通过.所以大多数搜索算法都需要优化.形象地看,搜索的优化过程就像将搜索树上没用的枝条剪下来,因此搜索的优化过程又叫剪枝.剪枝的实质就是通过判断决定是否要沿当前枝条走下去. 二.搜索的剪枝必需遵循三个原则: 1.正确性(不能把正解排除,要不然搜什么呢?)2.准确性(尽可能把不能通向正解的枝条剪去)3.高效性(因为在每个枝条上都要进行一次判断,如果判断的复杂

回溯深搜与剪枝初步

回溯算法也称试探法,一种系统的搜索问题的解的方法,是暴力搜寻法中的一种.回溯算法的基本思想是:从一条路往前走,能进则进.回溯算法解决问题的一般步骤: 根据问题定义一个解空间,它包含问题的解 利用适于搜索的方法组织解空间 利用深度优先法搜索解空间,并且在搜索过程中用剪枝函数避免无效搜索 回溯法采用试错的思想,它尝试分步的去解决一个问题.在分步解决问题的过程中,当它通过尝试发现现有的分步答案不能得到有效的正确的解答的时候,它将取消上一步甚至是上几步的计算,再通过其它的可能的分步解答再次尝试寻找问题的

深搜优化剪枝

之前做过不少深搜题,很多TLE,所以剪枝很重要,如何“未雨绸缪”,避免不必要的搜索树分支? 例题: 数的划分 将整数n分成k份,且每份不能为空,任意两份不能相同(不考虑顺序). 例如:n=7,k=3,下面三种分法被认为是相同的. 1,1,5: 1,5,1: 5,1,1: 问有多少种不同的分法. 输出一个整数,即不同的分法. 由题意得,其分发出现重复数字组合则为同一种算法,那么保证1-k个数递增即可 代码: #include<bits/stdc++.h> using namespace std;

深搜+DP剪枝 codevs 1047 邮票面值设计

codevs 1047 邮票面值设计 1999年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 给定一个信封,最多只允许粘贴N张邮票,计算在给定K(N+K≤40)种邮票的情况下(假定所有的邮票数量都足够),如何设计邮票的面值,能得到最大值MAX,使在1-MAX之间的每一个邮资值都能得到. 例如,N=3,K=2,如果面值分别为1分.4分,则在1分-6分之间的每一个邮资值都能得到(当然还有8分.9分和1

HDOJ/HDU Tempter of the Bone(深搜+奇偶性剪枝)

Problem Description The doggie found a bone in an ancient maze, which fascinated him a lot. However, when he picked it up, the maze began to shake, and the doggie could feel the ground sinking. He realized that the bone was a trap, and he tried despe

深搜的剪枝技巧

众所周知,搜索是个好东西,他能在很多时候(就是你不会正解打暴力的时候)派上用场. 然而搜索的时间复杂度实在是太高了,大多数都是指数级别的,这让人很是头疼 那么我来总结一下对搜索进行优化的技巧:剪枝 什么是剪枝 我们知道,搜索的进程可以看做遍历一棵搜索树的过程.而所谓的剪枝,就是通过某种判断,避免一些不必要的遍历过程. 形象的来说,就是剪掉搜索树上的一些枝条来达到减少遍历次数,缩短时间复杂度的效果 剪枝的原则 1.正确性 废话,你剪枝都把正确的答案剪了你还搜个啥呢? 2.准确性 尽可能多的剪去不需

HDU--1010 Tempter of the Bone(深搜+奇偶剪枝)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1010 我认为的剪枝就是在本来的代码中加入一些附加条件使之不去进行多余的计算,防止超时 奇偶剪枝的知识链接 AC代码: 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 int n,m,t,k,flag,starex,starey,endx,endy