http://poj.org/problem?id=1011

要把所给的集合分成几个集合,每个集合相加之和ans相等,且ans最小,因为这个和ans只在[1,64*50]内,所以可以用dfs一试

首先ans需要满足两个条件1.可以被总集合的和sum整除 2.是总集合的某个子集的和 对于条件1,可以通过试除遍历 对于条件2,可以通过dp预筛选,这两个花费时间都不大

接着搜索能不能划分成集合之和恰为ans的若干集合,

1. 可以从大向小找,因为大的更不灵活,而且所有的元素都需要取到

2.比如对于5,4,2,2,1 使用第一个2,向下找,没有找到答案,不用第一个2之后,也不需要再找第二,第三个2了

如果之前找过相同的数字了,那么之后就不用再找相同的数字

3.如果这次数字刚好组合成为一个ans,那么能不能组成由剩下的数字决定,也就是已经得到了一个新集合和为ans了,剩下的能够组成若干和为ans的集合则可以取ans,否则不能取ans

#include <cstdio>
#include<cstring>
#include <algorithm>
using namespace std;
int a[64],n;
bool cmp(int a,int b){return a>b;}
bool reachable[64*51];
bool used[64];
bool dfs(int s,int tmp,int sub){
// printf("s:%d tmp:%d sub:%d\n",s,tmp,sub);
used[s]=true;
tmp+=a[s];
if(tmp>sub){// 不可能出现
puts("ERROR");
used[s]=false;
return false;
}
if(tmp==sub){//恰好成为一个和为ans的集合
for(int i=0;i<n;i++){
if(!used[i]){
if(dfs(i,0,sub))return true;//dfs新的集合,直接返回剩下的元素能不能组合成若干和为ans的集合
else {
used[s]=false;
return false;
}
}
}
return true;//所有元素都被使用了
}
int f=-1;
for(int i=s+1;i<n;i++){
if(f==a[i]||used[i]){continue;}//如果这个状态的这个函数已经找过相同的数
if(tmp+a[i]==sub){//直接返回剩下的元素的组合状态
if(dfs(i,tmp,sub))return true;
else {
used[s]=false;
return false;
}
}
else if(tmp+a[i]<sub){//可以试着添加进这个集合
if(dfs(i,tmp,sub))return true;
}
f=a[i];
}
used[s]=false;
return false;
}
int main(){
while(scanf("%d",&n)==1&&n){
int sum=0,mx=0;
memset(reachable,false,sizeof(reachable));
for(int i=0;i<n;i++){
scanf("%d",a+i);
sum+=a[i];
mx=max(a[i],mx);
}
reachable[a[n-1]]=true;
reachable[0]=true;
sort(a,a+n,cmp);//从大到小搜索
for(int i=n-2;i>=0;i--){
for(int j=0;j<sum&&j+a[i]<=sum;j++){
if(reachable[j]){
reachable[j+a[i]]=true;//reachable[i]=true i可以被总集合中的某些元素加和得到
}
}
}
bool fnd=false;
for(int i=mx;i<sum;i++){
if(sum%i==0&&reachable[i]){
memset(used,0,sizeof(used));
if(dfs(0,0,i)){
printf("%d\n",i);
fnd=true;
break;
}
}
}
if(!fnd)printf("%d\n",sum);
} return 0;
}

  

POJ 1011 Sticks dfs,剪枝 难度:2的更多相关文章

  1. POJ 1011 - Sticks DFS+剪枝

    POJ 1011 - Sticks 题意:    一把等长的木段被随机砍成 n 条小木条    已知他们各自的长度,问原来这些木段可能的最小长度是多少 分析:    1. 该长度必能被总长整除    ...

  2. poj 1011 Sticks ,剪枝神题

    木棒 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 118943 Accepted: 27429 Description 乔治拿 ...

  3. DFS(剪枝) POJ 1011 Sticks

    题目传送门 /* 题意:若干小木棍,是由多条相同长度的长木棍分割而成,问最小的原来长木棍的长度: DFS剪枝:剪枝搜索的好题!TLE好几次,终于剪枝完全! 剪枝主要在4和5:4 相同长度的木棍不再搜索 ...

  4. 搜索+剪枝——POJ 1011 Sticks

    搜索+剪枝--POJ 1011 Sticks 博客分类: 算法 非常经典的搜索题目,第一次做还是暑假集训的时候,前天又把它翻了出来 本来是想找点手感的,不想在原先思路的基础上,竟把它做出来了而且还是0 ...

  5. poj 1011 Sticks (DFS+剪枝)

    Sticks Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 127771   Accepted: 29926 Descrip ...

  6. POJ 1011 Sticks 【DFS 剪枝】

    题目链接:http://poj.org/problem?id=1011 Sticks Time Limit: 1000MS   Memory Limit: 10000K Total Submissio ...

  7. poj 1011 :Sticks (dfs+剪枝)

    题意:给出n根小棒的长度stick[i],已知这n根小棒原本由若干根长度相同的长木棒(原棒)分解而来.求出原棒的最小可能长度. 思路:dfs+剪枝.蛮经典的题目,重点在于dfs剪枝的设计.先说先具体的 ...

  8. OpenJudge 2817:木棒 / Poj 1011 Sticks

    1.链接地址: http://bailian.openjudge.cn/practice/2817/ http://poj.org/problem?id=1011 2.题目: 总时间限制: 1000m ...

  9. uva 215 hdu 1455 uvalive5522 poj 1011 sticks

    //这题又折腾了两天 心好累 //poj.hdu数据极弱,找虐请上uvalive 题意:给出n个数,将其分为任意份,每份里的数字和为同一个值.求每份里数字和可能的最小值. 解法:dfs+剪枝 1.按降 ...

随机推荐

  1. css+js实现兼容性select的样式

    <!doctype html><html lang="en"> <head> <meta charset="UTF-8" ...

  2. Delphi 使用之函数

    函数由一句或多句代码组成,可以实现某个特定的功能.使用函数可以使代码更加易读.易懂,加快编程速度及减少重复代码.过程与函数类似,过程与函数最重要的区别在于,过程没有返回值,而函数能有返回值.     ...

  3. markdown 语法学习

    markdown是一种轻量级的标记语言,和html类似,但是易读性比html要好很多. 基本语法: 1.标题和正文分隔线 === //至少三个连续等号,最高阶标题 --- //或者三个连续的减号,第二 ...

  4. Machine Learning - 第6周(Advice for Applying Machine Learning、Machine Learning System Design)

    In Week 6, you will be learning about systematically improving your learning algorithm. The videos f ...

  5. Unity3d多线程

    http://blog.csdn.net/dingkun520wy/article/details/49181645 (一)多线程的创建 Thread t = new Thread(new Threa ...

  6. html+asp.net上传文件

    type="file" 的name以及id一定要写,并且名字相同 http://niunan.iteye.com/blog/479605 <form id="for ...

  7. 如何在大量jar包中搜索特定字符

    欢迎关注我的社交账号: 博客园地址: http://www.cnblogs.com/jiangxinnju/p/4781259.html GitHub地址: https://github.com/ji ...

  8. js对字符串函数之charAt()

    var str="012345"; 字符串下标的index从0开始: charAt(index)返回指定位置的字符如果index不在0-str.length之间,返回一个空字符串: ...

  9. 企业用户选择Java多于.NET的 5个原因

    .NET 和 Java 是当今社会最受欢迎的两种编程语言, 长期的发展和强大的功能使他们足以在编程界立足. 十余年的争论也没得到结果的一个话题就是——他们哪个更好一些? 今天, 我们不再去讨论JAVA ...

  10. Qt之可重入与线程安全

    简述 本篇文章中,术语"可重入性"和"线程安全"被用来标记类与函数,以表明它们如何被应用在多线程应用程序中. 一个线程安全的函数可以同时被多个线程调用,甚至调用 ...