Sticks HDU - 1455 (未完成)

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.

InputThe 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. OutputThe 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 <stdio.h>
#include <string.h>
#include <string>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;

int n,cnt,sum;//设置全局变量,n表示木棍的数量,sum表示n个木棍的总长度,cnt=sum/i;

struct node
{
  int lenth; // 木棍的长度
  int mark; //标记这根木棍是否被用过;
}stick[66];

int cmp(node a,node b) //按长度从大到小排序
{
    return a.lenth>b.lenth;
}

//len为当前木棒的长度,count统计当前长度木棒的数量,
int dfs(int len,int count,int l,int pos)
{
   if(len==sum) return 1; //递归出口
   if(count==cnt)   return 1;

   for(int i=pos;i<n;i++)
   {
      if(stick[i].mark)continue; //如果木棍被标记过,跳过去
      if(len==(stick[i].lenth+l))
      {
          stick[i].mark=1;
          if(dfs(len,count+1,0,0))  return 1;
          stick[i].mark=0;
          return 0;
      }
      else if(len>(stick[i].lenth+l))
      {
          stick[i].mark=1;
          l+=stick[i].lenth;
          if(dfs(len,count,l,i+1))
             return 1;
          l-=stick[i].lenth;  //如果不能拼接,那么就恢复
          stick[i].mark=0;
          if(l==0) return 0;
          while(stick[i].lenth==stick[i+1].lenth)i++;  //如果不剪支跑一遍要140MS,加上剪支跑一遍只要31MS,ORZ
      }
   }
  return 0;
}

int main()
{
        while(cin>>n&&n)
        {
           cnt=sum=0;
           for(int i=0;i<n;i++)
           {
               cin>>stick[i].lenth;
               sum+=stick[i].lenth;
               stick[i].mark=0;
           }
           sort(stick,stick+n,cmp);
           for(int i=stick[0].lenth;i<=sum;i++)
           {
              if(sum%i)continue;
              cnt=sum/i;
              if(dfs(i,0,0,0))
              {
                 printf("%d\n",i);
                 break;
              }
           }

        }
        return 0;
}

原文地址:https://www.cnblogs.com/astonc/p/9906810.html

时间: 2024-10-30 00:15:07

Sticks HDU - 1455 (未完成)的相关文章

HDU 1455——Sticks(神棍)

这题跟 HDU1518差不多 附上测试数据~~ 64 40 40 30 35 35 26 15 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 43 42 42 41 10 4 40 40 40 40 40 40 40 40 40 40 40 40 40 40 25 39 46 40 10 4 40 40 37 18 17 16 15 40 40 40 40 40 40 40 40 46 40 37 32 10 47 4 42 56 61 23 5

hdu 1455 Sticks——dfs经典的题目

http://acm.hdu.edu.cn/showproblem.php?pid=1455 题意:几根长度的棍子被分成了很多半.问合成多个长度相同的棍子,棍子长度最小是多少. 题解:很明显是dfs.所以我们首先需要找到,这些棍子可能是多长,肯定是最长的棍子的长度到所有棍子长度和之间的某个长度.找到这些可能之后就直接按照这个长度开始搜.想法是搜到和为这个长度之后记录,然后重新再搜,一直到所有棍子都分配自后就完成了. 重要的剪枝:确定每次搜索的起始位置,这个一定是确定的!!!其次就是相同长度的棍子

hdu 1455 sticks

经典剪枝题目,注释的别人代码.还是得自己多敲.反思,反思! 1 #include "iostream" 2 #include "algorithm" 3 #include "memory.h" 4 using namespace std; 5 6 int sticks[64],n,len,num; 7 bool used[64]; 8 9 bool cmp(int a,int b) 10 { 11 return a > b; 12 } 13

hdu 1455 Sticks DFS 又是一个花样剪枝 ,累觉不爱

Sticks Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6750    Accepted Submission(s): 1967 Problem Description George took sticks of the same length and cut them randomly until all parts becam

hdu 1455 hdu 1455 Sticks

思路还是很简单的,不过关键在于剪枝,用了几个不强力的剪枝,飘过~~~998ms #include<iostream> #include<algorithm> #include<cstring> #define maxn 65+5 using namespace std; int maxx,n,m,flag,l; int mapp[maxn]; int visit[maxn]; bool cmp(int x,int y) { return x>y; } void d

DFS/poj 1011/hdu 1455 Sticks

1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 using namespace std; 5 int n,tot,ans; 6 bool v[100]; 7 int a[100]; 8 bool cmp(int x,int y) 9 { 10 return x>y; 11 } 12 bool dfs(int now,int dep,int ans,int len) 13 { 14 if

hdu 1455 sticks(经典深搜+剪枝技巧)

 题意:有一堆的木棒,长度不一,它们是有一些整齐的木棒截断而成的,求最小的木棒原始长度. 思路很简单深搜,但是直接深搜的话会tle,首先可以对木棒长度进行排序从大到小,优先使用长度长的木棒,加入当前长度不符合,考虑下一个木棒 其次如果长度为零的时候选择木棒失败,那么直接退出,实测加上这一剪枝就可以ac,这一剪枝可以帮助我们尽可能的在靠近树根处剪枝,所以优化效果很明显. 然后是如果这次选择的木棒长度和上次失败时的一样,那么剪枝. #include<cstdio> #include<cs

HDU 1455(DFS_F题)解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1455 ----------------------------------------------------------------------------------- 题意:给出一定数量的小木棒的长度,它是由等长的若干木棒随意砍断所得到的.对于给定的一组小木棒,请求出可能的原始木棒的最小长度. 思路: 1.首先降序排列,因为木棍越长,可能的约束越大. 2.木棍的总长度除以原来的木棍数量,一定整

poj 1065 Wooden Sticks / hdu 1257 最少拦截系统 DP 贪心

参考链接:http://blog.csdn.net/xiaohuan1991/article/details/6956629 (HDU 1257 解题思路一样就不继续讲解) POJ 1065题意:给你n个木块,分别给出其长度和重量,然后要对这些木块进行加工,如果木块1的长度和重量都不大于木块2, 那么这两个木块可以放在一起加工,从而只用花费1个时间单位.问要如何进行加工从而能够花费最少时间单位. 知识点: 偏序集:若一个集合A为偏序集,那么满足:1.任意一个元素X属于集合,那么这个元素X≤X 2