poj1011 Sticks(dfs+剪枝)
| Time Limit: 1000MS | Memory Limit: 10000K | |
| Total Submissions: 110416 | Accepted: 25331 |
Description
Input
Output
Sample Input
9
5 2 1 5 2 1 5 2 1
4
1 2 3 4
0
Sample Output
6
5
一个dfs题,讲解我就copy点大神的了
经典搜索题,黑书上的剪枝例题。剪枝的空间很大,剪枝前写下朴素的搜索框架(黑字部分),枚举原始木棍的长度及由那些小木棍组合。原始木棍长度一定是小木棍总长度的约数,因此可以减少枚举量。
越长的木棍对后面木棍的约束力越大,因此要把小木棍排序,按木棍长度从大到小搜索,这样就能在尽可能靠近根的地方剪枝。(剪枝一)
如果当前木棍能恰好填满一根原始木棍,但因剩余的木棍无法组合出合法解而返回,那么让我们考虑接下来的两种策略,一是用更长的木棍来代替当前木棍,显然这样总长度会超过原始木棍的长度,违法。二是用更短的木棍组合来代替这根木棍,他们的总长恰好是当前木棍的长度,但是由于这些替代木棍在后面的搜索中无法得到合法解,当前木棍也不可能替代这些木棍组合出合法解。因为当前木棍的做的事这些替代木棍也能做到。所以,当出现加上某根木棍恰好能填满一根原始木棍,但由在后面的搜索中失败了,就不必考虑其他木棍了,直接退出当前的枚举。(剪枝二)
显然最后一根木棍是不必搜索的,因为原始木棍长度是总木棍长度的约数。(算不上剪枝)
考虑每根原始木棍的第一根木棍,如果当前枚举的木棍长度无法得出合法解,就不必考虑下一根木棍了,当前木棍一定是作为某根原始木棍的第一根木棍的,现在不行,以后也不可能得出合法解。也就是说每根原始木棍的第一根小木棍一定要成功,否则就返回。(剪枝四)
剩下一个通用的剪枝就是跳过重复长度的木棍,当前木棍跟它后面木棍的无法得出合法解,后面跟它一样长度的木棍也不可能得到合法解,因为后面相同长度木棍能做到的,前面这根木棍也能做到。(剪枝五)
这题主要就是剪枝,看了别人的代码看了好久才写的
#include<iostream>
#include<algorithm>
using namespace std; int a[70],visit[70],len,n; bool cmp(const int a,const int b)
{
return a>b;
} bool dfs(int f,int i,int sum)
{
int j;
if(i==0)
{
if(sum==len)
return true;//全部的都已经找完了,都匹配
i=len;
for(j=0;visit[j];j++)
;
visit[j]=1;
if(dfs(j+1,i-a[j],sum-len))//此处j+1是因为j已经搜过了
{
return true;
}
visit[j]=0;//失败了
}
else
{
for(j=f;j<n;j++)
{
if(visit[j])
continue;
if(j>0&&a[j]==a[j-1]&&!visit[j-1])
{
continue;
}
visit[j]=1;
if(a[j]<=i&&dfs(j+1,i-a[j],sum))//这里j+1和上面意思一样,原来看别人的写的是j,让我纠结了好久,加不加1只是对结果没影响
return true;
visit[j]=0;
if(a[j]==i)//刚好把木棒填满,并且搜索失败,这种情况不可能了,无论如何满足不了题意的
break;
}
}
return false;
}
int main()
{
int i,j,sum;
while(scanf("%d",&n)!=EOF&&n)
{
for(i=0;i<n;i++)
visit[i]=0;
sum=0;
for(i=0;i<n;i++)
{
scanf("%d",a+i);
sum+=a[i];
}
sort(a,a+n,cmp);
j=sum/2;
for(i=a[0];i<=j;i++)
{
len=i;
if(sum%i==0)
{
if(dfs(0,i,sum))//序号,还差的长度(不包括当前棒),总木棒剩余的长度
break;//这个dfs有点特殊,dfs里面的意思不太一样,它没有标记0,这是为了方便写
}
}
if(i>j)
printf("%d\n",sum);
else printf("%d\n",i);
}
return 0;
}
/*
9
5 2 1 5 2 1 5 2 1
4
1 2 3 4
*/
poj1011 Sticks(dfs+剪枝)的更多相关文章
- poj1011(DFS+剪枝)
题目链接:https://vjudge.net/problem/POJ-1011 题意:给定n(<=64)条木棍的长度(<=50),将这些木棍刚好拼成长度一样的若干条木棍,求拼出的可能的最 ...
- poj 1011 :Sticks (dfs+剪枝)
题意:给出n根小棒的长度stick[i],已知这n根小棒原本由若干根长度相同的长木棒(原棒)分解而来.求出原棒的最小可能长度. 思路:dfs+剪枝.蛮经典的题目,重点在于dfs剪枝的设计.先说先具体的 ...
- POJ1011 (DFS+剪枝)
Sticks Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 129606 Accepted: 30388 Descrip ...
- POJ 1011 - Sticks DFS+剪枝
POJ 1011 - Sticks 题意: 一把等长的木段被随机砍成 n 条小木条 已知他们各自的长度,问原来这些木段可能的最小长度是多少 分析: 1. 该长度必能被总长整除 ...
- poj1011 && uva307 DFS + 剪枝
将木棒从大到小排列,保证每次的选择都是最长可选的木棒. 剪枝: 1 . 如果第 i 根木棒被选择却无法成功拼接,那么后面与其长度相同的也不能选择. 2 . 如果第 cnt + 1 根木棒无法成功拼接, ...
- hdu 1145(Sticks) DFS剪枝
Sticks Problem Description George took sticks of the same length and cut them randomly until all par ...
- POJ 1011 Sticks dfs,剪枝 难度:2
http://poj.org/problem?id=1011 要把所给的集合分成几个集合,每个集合相加之和ans相等,且ans最小,因为这个和ans只在[1,64*50]内,所以可以用dfs一试 首先 ...
- DFS(剪枝) POJ 1011 Sticks
题目传送门 /* 题意:若干小木棍,是由多条相同长度的长木棍分割而成,问最小的原来长木棍的长度: DFS剪枝:剪枝搜索的好题!TLE好几次,终于剪枝完全! 剪枝主要在4和5:4 相同长度的木棍不再搜索 ...
- poj 1011 Sticks (DFS+剪枝)
Sticks Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 127771 Accepted: 29926 Descrip ...
随机推荐
- Grails教程
1简介- Reference DocumentationVersion:null Table of Contents 1.1Grails 2.0有那些新特性?1.1.1面向开发的特性1.1.2核心特性 ...
- [React Testing] className with Shallow Rendering
The React Shallow Renderer test utility lets us inspect the output of a component one level deep. In ...
- Eclipse Removing obsolete files from server 问题
今天在修改server.xml调试程序时,遇到下面这个问题,clean,重启都不好使. Removing obsolete files from server.. ...
- C#。总结
数据类型--变量与常量--运算符与表达式--语句(if,for)--数组--函数--结构体一.数据类型: (一)内建类型 整型(int short long byte uint ushort ulon ...
- JobDeer 的《程序员必读的职业规划书》
JobDeer 的<程序员必读的职业规划书> 关键字 持续性,人生规划,职业规划 概念 职业规划三部分: 职业定位 目标设定 通道设计 职业价值论: 能为公司做什么 同样的能力再不同公司价 ...
- 有几数组表单,js怎么获得数组并动态相加输出到文本框
有几数组表单,js如何获得数组并动态相加输出到文本框<input name= "fee1[] "> <input name= "fee2[] & ...
- POI创建Excle
1.导包 2.Demo Workbook wb=new HSSFWorkbook();//创建工作空间 Sheet sh= wb.createSheet("工作表1");//创建工 ...
- poj2409
用n个颜色的珠子编项链,求有多少种情况 由N(G,C) = 所有f的稳定核的和/|G| m边形有m种旋转m种翻转 首先说旋转,有模线性方程可知每种旋转都有gcd(m,i)个循环节且每个循环节长度为n/ ...
- xode 中文乱码处理
find *.* -exec sh -c "iconv -f GB18030 -t UTF-8 {} > {}.txt" \;
- C#必须掌握的系统类
系统类 Type类,Object类,String类, Arrary类,Console类, Exception类,GC类, MarshalByRefObject类, Math类. DateTime结构 ...