题目大意:

乔治有一些碎木棒,是通过将一些相等长度的原始木棒折断得到的,给出碎木棒的总数和各自的长度,求最小的可能的原始木棒的长度;(就是将一些正整数分组,每组加起来和相等,使和尽可能小)

一开始做poj 32ms过,但uva3000 ms 都超时。。。而且poj discuss里给出了一组bT数据,最后uva 0.2sac的代码也跑了3 。4秒左右。discuss里的大牛据说什么奇偶性剪枝0.01ms过,可惜搜了半天也没找到具体方法。这题就这样过好了。。(参考各种空间博客才艰难ac。不过此题实在是太经典了,搜索学习剪枝必做)

对于这道题而言,剪枝的策略一般有下面6个:

①先将木棒长度从大到小进行排序,这样便于后面的选择和操作,是后面一些剪枝算法的前提。

②在枚举原木棒长度时,枚举的范围为max与sum/2之间,如果这个区间内没有找到合适的长度,那么最后原木棒的长度只能是sum。

③枚举的原木棒的长度只能是sum的约数。

④在深搜过程中,如果当前木棒和前一个木棒的长度是一样的,但是前一个木棒没有被选上,那么这个木棒也一定不会被选上。

⑤在深搜过程中,如果当前是在拼一根新木棒的第一截,但如果把可用的最长的一根木棒用上后不能拼成功的话,那么就不用再试后面的木棒了,肯定是前面拼的过程出了问题。

⑥在深搜过程中,如果当前可用的木棒恰好能补上一根原木棒的最后一截,但用它补上之后却不能用剩下的木棒完成后续的任务,那么也不用再试后面的木棒了,肯定是前面拼的过程出了问题。

参考博客:http://www.cnblogs.com/staginner/archive/2011/09/08/2171329.html

我的AC 代码:(剪枝见注释)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
 
int n,max_len,min_len,sum,ans,num,flag;
int a[10000],v[10000];
 
bool cmp(const int &x,const int &y)
{
     return !(x<y);
}
 
void search(int step,int from,int cur)//step表示当前去凑的是第几根原始棒,order表示当前用了多少根碎棒子来凑第step根
{
     //printf("%d %d\n",step,cur);
    if (cur==ans)
    {
       if (step==num)
       {
          flag=1;
          return;
       }
       int k;
       for (k=1;k<=n && v[k];k++);
       v[k]=1;
       search(step+1,1,a[k]);
       v[k]=0;
       return;
    }
    for (int i=from;i<=n;i++)
    {
        if (v[i])
           continue;
        if (cur+a[i]>ans)
           continue;
        if (a[i]==a[i-1] && !v[i-1])
           continue;//剪枝3:上一根棒和目前这根一样并且没用过,那么用这一根去凑和用上一根去凑结果一样都不能出解
        //printf("kk %d %d\n",cur,cur+a[i]);
        int t=a[i]+cur;
        if (t!=ans && t+min_len>ans)
           continue;
        v[i]=1;
        search(step,i+1,t);
        v[i]=0;
        if (t==ans)
           return;
        if (flag || cur==0)//剪枝4:如果当前用了1根碎棒子来凑,枚举了第一根碎棒不能出解那么跳出
           return;
    }
    return;
}
 
int main ()
{
    while (scanf("%d",&n)==1)
    {
          if (n==0)
             break;
          v[0]=1;
          a[0]=210000000;
          max_len=-1;
          min_len=21000000;
          sum=0;
          flag=0;
          for (int i=1;i<=n;i++)
          {
              scanf("%d",&a[i]);
              if (a[i]>max_len)
                 max_len=a[i];
              if (a[i]<min_len)
                 min_len=a[i];
              sum+=a[i];
          }
          sort(a+1,a+n+1,cmp);
          for (ans=max_len;ans<=sum/2;ans++)//剪枝1:答案的下界为最长的棒,上界为长度总和
          {
              if (sum%ans!=0)
                 continue;//剪枝 2:原始棒长度是总长度的约数
              for (int k=1;k<=n;k++)
                  v[k]=0;
              num=sum/ans;
              search(1,1,0);
              if (flag)
              {
                  printf("%d\n",ans);
                  break;
              }
          }
          if (!flag)
             printf("%d\n",sum);
    }
    return 0;
}

Sticks(poj1011/uva307)的更多相关文章

  1. poj1011 Sticks(DFS+剪枝)

    题目链接 http://poj.org/problem?id=1011 题意 输入n根棍子的长度,将这n根棍子组合成若干根长度相同的棍子,求组合后的棍子的最小长度.这题是poj2362的加强版,思路与 ...

  2. poj-1011 sticks(搜索题)

    George took sticks of the same length and cut them randomly until all parts became at most 50 units ...

  3. poj1011 Sticks (dfs剪枝)

    [题目描述] George took sticks of the same length and cut them randomly until all parts became at most 50 ...

  4. UVA-307 Sticks (DFS+剪枝)

    题目大意:用n根长度未必相等的木棒匹配出最多数量的等长木棒. 题目分析:枚举所有可能的等长木棒的长度,通过DFS的方式逐根匹配,在此过程中要剪枝.先将木棒长度按从大到小排序,也就是说匹配每一根等长木棒 ...

  5. 2018.07.03 POJ 2653 Pick-up sticks(简单计算几何)

    Pick-up sticks Time Limit: 3000MS Memory Limit: 65536K Description Stan has n sticks of various leng ...

  6. POJ2653:Pick-up sticks(线段相交)

    题目:http://poj.org/problem?id=2653 题意:题意很简单,就是在地上按顺序撒一对木棒,看最后有多少是被压住的,输出没有被压住的木棒的序号.(有点坑的就是没说清楚木棒怎么算压 ...

  7. Sticks(剪枝+BFS)

    Problem Description George took sticks of the same length and cut them randomly until all parts beca ...

  8. hdu 1455 Sticks(dfs+剪枝)

    题目大意: George有许多长度相同的木棍,随机的将这些木棍砍成小木条,每个小木条的长度都是整数单位(长度区间[1, 50]).现在George又想把这些小木棒拼接成原始的状态,但是他忘记了原来他有 ...

  9. 2015 CCPC D- Pick The Sticks(UESTC 1218) (01背包变形)

    http://acm.uestc.edu.cn/#/problem/show/1218 既然二维dp表示不了,就加一维表示是否在边界放置,放置一个,两个.有一个trick就是如果只放一根,那么多长都可 ...

随机推荐

  1. js的小随笔

    1.在js中{  }中的块级语句没有独立的作用域 var i = 5;for(; i < 8; i++){ console.log(i); } //输出 5 6 7 //全局设置的变量i在for ...

  2. poj1039Pipe(直线交点、叉积)

    链接 之前刷poj计划时刷过,不过也没什么印象了.打铁还是趁热,还没热起来就放弃了,前面算是做了无用功,有如胡乱的看解题报告一样. 题目应该是比较经典的集合入门题,黑书上有一部分核心讲解. 题目中的最 ...

  3. MVC中Url请求与控制器的默认约定

    1.请求的url如:http://localhost:52481/Home/Browse?genre=1控制器方法:public string Browse(string genre) //这里返回值 ...

  4. js获取字符串的字节长度

    占用3个字节的范围 U+2E80 - U+2EF3 : 0xE2 0xBA 0x80 - 0xE2 0xBB 0xB3 共 115 个 U+2F00 - U+2FD5 : 0xE2 0xBC 0x80 ...

  5. 将spring管理的bean使用注解的方式注入到servlet中

    Filter和Servlet中不能直接注解使用spring的bean,因为这两个都是servlet容器维护管理的,当然也有实现方法,如下: 1.创建一个AbstractServlet 抽象类,让你的所 ...

  6. China Brain Project: Basic Neuroscience, Brain Diseases, and Brain-Inspired Computing

    日前,中国科学院神经科学研究所.中国科学院脑科学与智能技术卓越创新中心.香港科技大学生命科学部和分子神经科学国家重点实验室.中国科技大学自动化研究所在 Cell 上联合发表了一篇概述论文<Chi ...

  7. APMServ本地搭建网站最好用的软件

    APMServ 5.2.6 是一款拥有图形界面的快速搭建Apache 2.2.9.PHP 5.2.6.MySQL 5.1.28&4.0.26.Nginx 0.7.19.Memcached 1. ...

  8. linux笔记:压缩解压命令gzip,gunzip,tar,zip,unzip,bzip2,bunzip2

    命令名称:gzip功能:压缩文件命令所在路径:/bin/gzip用法:gzip 文件压缩后文件格式:.gz其他:压缩后不保留原文件:只能压缩文件,不能压缩目录 命令名称:gunzip功能:解压.gz格 ...

  9. Mybatis那一大堆事儿--1

    <select id="listAmPerfTime" resultType="Date"> SELECT pam.perf_time AS per ...

  10. Sublime Text 3编辑器安装

    一.安装Sublime Text 3 到Sublime Text 3官网下载最新版本:http://www.sublimetext.com/3 一路Next下去即可完成安装.安装完Sublime Te ...