poj(1011)——Sticks(经典的dfs+剪枝)
题目的大致意思是:
如今有n根木棍,然后须要把它们拼成相同长度的木棍,问满足这个条件的最短的长度是多少?
想法嘛:那肯定是dfs把长度搜一遍就好,但问题的关键是这里会超时。那么就要用到剪枝的原理了。
下面部分是来自于pku的gw老师说哒
1)不要在同一个位置多次尝试同样长度的木棒(在某一次拼接时选择长度为s的木棒导致拼接失败。则在同一位置尝试下一根木棒时。要跳过全部长度为s的木棒)
2)假设因为以后的拼接失败。须要又一次调整第i根棍子的拼法,则不会考虑替换第i根棍子中的第一根木棒。
3)不要希望通过只替换已经拼好的棍子的最后一根木棒就能改变失败的局面。
4)拼每一根棍子的时候,应确保已经拼好的部分,长度是从长到短排列的(由于我们应该先拼长的,长的可能性小)
排除方法:每次找一根木棒的时候,仅仅要这不是一根棍子的第一条木棒。那么不应该从下标为0的木棒開始找,而应该从刚刚接上去的那条木棒的下一条開始找(当然。我们要先对木棒进行从大到小的排序)
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
using namespace std;
#define maxn 70
int a[maxn],n,L,vis[maxn],lastnum=0;
bool cmp(int a,int b){
return a>b;
}
//当前还余下的棍子的个数和还缺的长度
bool dfs(int m,int l){
if(m==0&&l==0) return true;
if(l==0) l=L;
int s=1;
//剪枝4
if(l!=L){
s=lastnum+1;
}
for(int i=s;i<=n;i++){
if(!vis[i-1]&&i>1&&a[i]==a[i-1]) continue; //剪枝1
if(!vis[i]&&a[i]<=l){
vis[i]=1;
lastnum=i;
if(dfs(m-1,l-a[i])) return true;
else{
vis[i]=0;
if(L==l||a[i]==l) return false; //剪枝2,3
}
}
}
return false;
}
int main(){
while(~scanf("%d",&n)){
if(n==0) break;
memset(a,0,sizeof(a));
int sum=0,lmax=-1;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
if(a[i]>lmax) lmax=a[i];
sum+=a[i];
}
int i=0;
sort(a+1,a+1+n,cmp);
#if 1
for(i=lmax;i<=sum/2;i++){
if(sum%i) continue;
L=i;
memset(vis,0,sizeof(vis));
lastnum=0;
if(dfs(n,i)){
printf("%d\n",i);
break;
}
}
if(i>sum/2) printf("%d\n",sum);
#endif
}
}
/*
9
5 2 1 5 2 1 5 2 1
4
1 2 3 4
0
*/
poj(1011)——Sticks(经典的dfs+剪枝)的更多相关文章
- DFS(剪枝) POJ 1011 Sticks
题目传送门 /* 题意:若干小木棍,是由多条相同长度的长木棍分割而成,问最小的原来长木棍的长度: DFS剪枝:剪枝搜索的好题!TLE好几次,终于剪枝完全! 剪枝主要在4和5:4 相同长度的木棍不再搜索 ...
- POJ 1011 - Sticks DFS+剪枝
POJ 1011 - Sticks 题意: 一把等长的木段被随机砍成 n 条小木条 已知他们各自的长度,问原来这些木段可能的最小长度是多少 分析: 1. 该长度必能被总长整除 ...
- 搜索+剪枝——POJ 1011 Sticks
搜索+剪枝--POJ 1011 Sticks 博客分类: 算法 非常经典的搜索题目,第一次做还是暑假集训的时候,前天又把它翻了出来 本来是想找点手感的,不想在原先思路的基础上,竟把它做出来了而且还是0 ...
- OpenJudge 2817:木棒 / Poj 1011 Sticks
1.链接地址: http://bailian.openjudge.cn/practice/2817/ http://poj.org/problem?id=1011 2.题目: 总时间限制: 1000m ...
- poj 1011 Sticks (DFS+剪枝)
Sticks Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 127771 Accepted: 29926 Descrip ...
- POJ 1011 Sticks 【DFS 剪枝】
题目链接:http://poj.org/problem?id=1011 Sticks Time Limit: 1000MS Memory Limit: 10000K Total Submissio ...
- POJ 1011 Sticks(搜索 && 剪枝 && 经典)
题意 : 有n根木棍(n<=64),它们由一些相同长度的木棍切割而来,给定这n根木棍的长度,求使得原来长度可能的最小值. 分析 : 很经典的深搜题目,我们发现答案只可能是所有木棍长度总和的因数, ...
- poj 1011 Sticks ,剪枝神题
木棒 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 118943 Accepted: 27429 Description 乔治拿 ...
- uva 215 hdu 1455 uvalive5522 poj 1011 sticks
//这题又折腾了两天 心好累 //poj.hdu数据极弱,找虐请上uvalive 题意:给出n个数,将其分为任意份,每份里的数字和为同一个值.求每份里数字和可能的最小值. 解法:dfs+剪枝 1.按降 ...
随机推荐
- python爬虫基础08-selenium大全2/8-Chrome Webdriver启动选项
Selenium笔记(2)Chrome Webdriver启动选项 本文集链接:https://www.jianshu.com/nb/25338984 在Selenium中使用不同的Webdriver ...
- Python函数高级
函数对象 在面向对象编程中 一切皆对象 函数在python中是第一类对象 函数可以这么用 可以被引用 def func(): print('hello world !') f=func f() 可 ...
- (转)iOS开发之Pch预编译文件的创建
本文转自 http://www.cnblogs.com/496668219long/p/4568265.html 在Xcode6之前,创建一个新工程xcode会在Supporting files文件夹 ...
- Leetcode 413.等差数列划分
等差数列划分 如果一个数列至少有三个元素,并且任意两个相邻元素之差相同,则称该数列为等差数列. 例如,以下数列为等差数列: 1, 3, 5, 7, 9 7, 7, 7, 7 3, -1, -5, -9 ...
- ffmpeg常见名词解析
scan_all_pmts, 扫描全部的ts流的"Program Map Table"表.
- 九度oj 题目1342:寻找最长合法括号序列II
题目描述: 假如给你一个由’(‘和’)’组成的一个随机的括号序列,当然,这个括号序列肯定不能保证是左右括号匹配的,所以给你的任务便是去掉其中的一些括号,使得剩下的括号序列能够左右括号匹配且长度最长,即 ...
- mysql5.7.23版本安装教程
亲身实践安装mysql,用时居然花费了三个小时,在有那么多教程的情况下,依然在不该花费时间的路上浪费了太多时间.希望这篇文章能够帮助大家少走弯路~~ 1.下载我下载的是64位. 2.解压下载之后,我选 ...
- hdu 1104 数论+bfs
Remainder Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total ...
- NOIP[2015] 运输计划(codevs 4632)
题目描述 Description 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个星球,还有 n−1 条双向航道,每条航道建立在两个星球之间,这 n−1 条航道连通了 L 国的所有星球.小 P ...
- 【HDOJ6223】Infinite Fraction Path(后缀数组,倍增)
题意: 给一个长度为n的字符串s[0..n-1],但i的后继不再是i+1,而是(i*i+1)%n,求所有长度为n的“子串”中,字典序最大的是谁 n<=150000,s[i]=0..9 思路:后缀 ...