http://poj.org/problem?id=1011 (题目链接)

题意

  给出一大堆小棍子的长度,需要把他们拼成几根长度相等的大棍子,求大棍子的最短长度。

Solution

  经典搜索题,剪枝剪到手软。

  要得到最小的原始木棍长度,可以按照分段数的长度,依次枚举所有的可能长度L。每次枚举L时,dfs判断是否能用小木棍拼合出整数个L。如果不剪枝,就等着狂TLE吧。

  最优性:

    1.所有木棍的长度和一定能一定能整除大木棍长度L。

    2.大木棍长度一定>=小木棍最长长度。

  可行性:

    3.一只长木棍肯定比几枝短木棍拼成同样长度的用处小,即短小的可以更灵活组合,所以可以对输入的所有木棍按长度排序。

    4.当用木棍i拼合大木棍时,可以从第i+1后的木棍开始搜。因为根据剪枝3,i前面的木棍已经用过了。

    5.用当前最长长度的木棍开始搜,如果拼不出当前设定的L,直接return。

    6.相同长度的木棍不要搜多次。

    7.判断搜到的几根木棍组成长度是否大于L,若大于,return。

    8.判断当前剩下的木棍根数是否够拼的木棍数。

  这里用了一个小小的技巧,函数互相调用,详情见代码。

代码

// poj1011
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define inf 2147483640
#define Pi 3.1415926535898
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
using namespace std; int n,m,ans,length,a[100010],times,sum;
bool b[100010],flag; void fit(int x);
void dfs(int x,int len,int lev) {
if (len==length) {fit(x+1);return;}
for (int i=lev+1;i<=n;i++)
if (!b[i] && len+a[i]<=length) {//剪枝5,7
if (n-times+1<ans-x) return;//剪枝8
b[i]=1;
times++;
dfs(x,len+a[i],i);
times--;
b[i]=0;
int j=i;
if (flag) return;
while (i<n && a[i]==a[j]) i++;//剪枝6
if (i==n) return;
if (i!=j) i--;
}
}
void fit(int x) {
int t;
if (x>=ans) {flag=1;return;}
for (int i=1;i<=n;i++) if (!b[i]) {t=i;break;}//剪枝4
b[t]=1;
times++;
dfs(x,a[t],t);
times--;
b[t]=0;
}
bool cmp(int a,int b) {return a>b;}
int main() {
while (scanf("%d",&n)==1) {
if (n==0) break;
sum=0;int maxl=0;
for (int i=1;i<=n;i++) {
scanf("%d",&a[i]);
maxl=max(maxl,a[i]);
sum+=a[i];
}
sort(a+1,a+1+n,cmp);//排序,剪枝3
memset(b,0,sizeof(b));
for (int i=n;i>=1;i--) {
ans=i;length=sum/i;
if (i==1) break;
if (sum%i>0 || length<maxl) continue;//剪枝1,2
memset(b,0,sizeof(b));
times=0;
flag=0;
fit(1);
if (flag) break;
}
printf("%d\n",sum/ans);
}
return 0;
}

  

【poj1011】 Sticks的更多相关文章

  1. 【POJ1011】Sticks

    [题目概括] 现在有\(n\)个长度不超过\(50\)的木棍,请你把这些小木棍拼成若干根长度相同的木棍. 请你最小化拼成后的长度. [思路要点] 考虑枚举最后的长度,然后判断是否可以,这样就不需要最优 ...

  2. 【bfs】拯救少林神棍(poj1011)

    Description 乔治拿来一组等长的木棒,将它们随机地砍断,使得每一节木棍的长度都不超过50个长度单位.然后他又想把这些木棍恢复到为裁截前的状态,但忘记了初始时有多少木棒以及木棒的初始长度.请你 ...

  3. 【POJ 1011】 Sticks

    [题目链接] http://poj.org/problem?id=1011 [算法] 深搜剪枝 首先我们枚举木棍的长度i,那么就有s/i根木棍,其中s为木棍长度的总和,朴素的做法就是对每种长度进行搜索 ...

  4. 【Uva 307】Sticks

    [Link]: [Description] 给你最多n个棍子; (n< = 64) 每根棍子长度(1..50) 问你这n根棍子,可以是由多少根长度为x的棍子分割出来的; x要求最小 [Solut ...

  5. 【转】欧拉回路&特殊图下的哈密顿回路题集

    转自:http://blog.csdn.net/shahdza/article/details/7779385 欧拉回路[HDU]1878 欧拉回路 判断3018 Ant Trip 一笔画问题1116 ...

  6. 【转载】图论 500题——主要为hdu/poj/zoj

    转自——http://blog.csdn.net/qwe20060514/article/details/8112550 =============================以下是最小生成树+并 ...

  7. HDU 5914 Triangle 【构造】 (2016中国大学生程序设计竞赛(长春))

    Triangle Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Su ...

  8. 【HDOJ图论题集】【转】

    =============================以下是最小生成树+并查集====================================== [HDU] How Many Table ...

  9. 【LeetCode】深搜DFS(共85题)

    [98]Validate Binary Search Tree [99]Recover Binary Search Tree [100]Same Tree [101]Symmetric Tree [1 ...

随机推荐

  1. Java 集合系列01之 总体框架

      Java集合是java提供的工具包,包含了常用的数据结构:集合.链表.队列.栈.数组.映射等.Java集合工具包位置是java.util.*Java集合主要可以划分为4个部分:List列表.Set ...

  2. usb驱动开发13之设备生命线

    上一节勉勉强强把struct urb这个中心给说完,接着看那三个基本点. 第一个基本点,usb_alloc_urb函数,创建urb的专用函数,为一个urb申请内存并做初始化,在drviers/usb/ ...

  3. VS2013 抛出 stackoverflow exception 的追踪

    本公司使用VWG.Caslte ActiveRecord.CSLA.net .Quantz.net 等组件做为公司的开发基础,自2007年以来,一直工作正常,但最近(2015.12月)以来,打开MDA ...

  4. PRML读书会第九章 Mixture Models and EM(Kmeans,混合高斯模型,Expectation Maximization)

    主讲人 网络上的尼采 (新浪微博: @Nietzsche_复杂网络机器学习) 网络上的尼采(813394698) 9:10:56 今天的主要内容有k-means.混合高斯模型. EM算法.对于k-me ...

  5. JSON拾遗

    最近开始翻<JavaScript高级程序设计>,其实很多大师级人物都推荐这本书为JavaScript入门级读物.因为第20章 JSON篇幅最小,而且以前也写过一篇JSON的总结JSON简介 ...

  6. java并发:阻塞队列

    第一节 阻塞队列 1.1 初识阻塞队列 队列以一种先进先出的方式管理数据,阻塞队列(BlockingQueue)是一个支持两个附加操作的队列,这两个附加的操作是:在队列为空时,获取元素的线程会等待队列 ...

  7. windows部署React-Native的开发环境实践(技术细节)

    前情摘要 众所周知,有人说.net可以用Xamrian,呵呵,不习惯收费的好么?搞.Net的人设置一次java的环境变量,可能都觉得实在太麻烦了,可能是因为这些年微软确实把我们给带坏了,所有东西一键安 ...

  8. 重叠(Overlapping) NAT

    当内部网络也使用公网注册地址(或者是外网合法地址)时,如果仍使用标准的静态或者动态NAT转换,则可能使得转换的内网地址与外网中合法地址冲突,使数据包又返回到了本地网络,这肯定是不行的.这时我们就要使用 ...

  9. jni的使用方法

    我们可以通过jni来调用c/c++程序,C/C++一般会被作为动态库的形式来供java程序调用 环境 操作系统:Centos6.7 java: openjdk7 依赖包:java7-devel(yum ...

  10. 63-w 简明笔记

    显示关于系统用户的信息 w [options] [username] w用于显示当前登录系统的用户的名字以及他们的终端设备编号.登录时间.正在运行的命令和其他一些信息 参数 username 限定仅显 ...