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插件,pycharm基本用法,markdown文本编写,jupyter notebook的基本操作汇总
5.14自我总结 一.python插件插件相关技巧汇总 安装在cmd上运行 #比如安装 安装:wxpy模块(支持 Python 3.4-3.+ 以及 2.7 版本):pip3 install wxpy ...
- Django中重定向页面的时候使用命名空间
urls.py from django.urls import path from . import views app_name='front' urlpatterns = [ path('',vi ...
- solr DIH 设置定时索引
1 web.xml中加入 web.xml所在目录 /opt/solr-7.7.1/server/solr-webapp/webapp/WEB-INF <listener> <list ...
- iOS 引入支付宝 缺少 #include <openssl/asn1.h>
出现情况如上图: 解决方法如下:在你的Xcode里的header search paths 里添加支付宝SDK(openssl的路径):格式如下 $(PROJECT_DIR)/文件夹名 ...
- Nmap手册
转自:http://drops.xmd5.com/static/drops/tips-4333.html 0x00:说明 只是一个快速查询手册,理论的东西都没有补充,欢迎大家积极在评论区补充自己常用的 ...
- deine const 等关键字区别
define 属于预编译指令,在程序运行之前就已经编译好:额,定义变量,没有类型信息, const 修饰的变量是不可变的,只是给出了内存地址,且只在程序运行时初始化开辟一块内存空间 const 只修饰 ...
- HDU 5514 Frogs
Frogs Time Limit: 1000ms Memory Limit: 65536KB This problem will be judged on HDU. Original ID: 5514 ...
- python3--__repr_和__str__会返回字符串表达形式
__repr_和__str__会返回字符串表达形式 下一个例子是已经见过的init构造方法和add重载方法,本例也会定义返回实例的字符串表达形式的__repr__方法.字符串格式把self.data对 ...
- 【JavaScript 4—基础知识点】:函数
导读:函数这个东西,从VB开始就一直在用,不过那时候一般写不出来自己的函数或者类,觉得最高大上的,就是调用API函数了.现在,学习到了JavaScript,总结总结函数,显得很有必要.这篇文章,就从最 ...
- POJ 2411 Mondriaan's Dream ——状压DP 插头DP
[题目分析] 用1*2的牌铺满n*m的格子. 刚开始用到动规想写一个n*m*2^m,写了半天才知道会有重复的情况. So Sad. 然后想到数据范围这么小,爆搜好了.于是把每一种状态对应的转移都搜了出 ...