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. (一)stm32之CMSIS标准、库目录、GPIO

    一.CMSIS标准 ST公司的stm32采用的是cortex-m3内核,内核是整个微处理器的CPU.该内核是ARM公司设计的一种处理器体系架构.内核与外设的关系就像PC上的CPU与硬盘.主板.内存等的 ...

  2. 5.7 C和C++的关系

  3. K均值聚类(Kmeans)

    Sigma = [1, 0; 0, 1]; mu1 = [1, -1]; x1 = mvnrnd(mu1, Sigma, 200); mu2 = [5.5, -4.5]; x2 = mvnrnd(mu ...

  4. 基于gralde搭建spring boot项目

    搭建基于gradle的sprint boot项目,swagger-ui辅助 spring boot官网:http://projects.spring.io/spring-boot/get start ...

  5. C 语言字符串连接的 3种方式

    C 语言字符串连接的 3种方式 #include<stdio.h> #include<stdlib.h> #include<string.h> char *join ...

  6. 串行通讯之.NET SerialPort异步写数据

    目录 第1章说明    2 1 为什么需要异步写数据?    2 2 异步写数据的代码    2 3 源代码    4 第1章说明 1 为什么需要异步写数据? 如下图所示,以波特率300打开一个串口. ...

  7. MySQL锁监视器

    还在为看不懂何登成的加锁处理分析文章感到羞愧吗? 还在因为何大师的笔误,陷入深深的迷茫吗? 只要你拥有大于5.6.16版本的MySQL,锁监视器你值得拥有! 快速入门 开启 set GLOBAL in ...

  8. 能源项目xml文件标签释义--<mvc:annotation-driven>

    <mvc:annotation-driven />的可选配置 <mvc:annotation-driven message-codes-resolver ="bean re ...

  9. Unity Invoke 方法

    Invoke() 方法是 Unity3D 的一种委托机制 如: Invoke("a", 5);   它的意思是:5 秒之后调用 a() 方法: 使用 Invoke() 方法需要注意 ...

  10. IO流--字节流

    import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileInputStream; import ...