P1120 小木棍 [数据加强版]

题目描述

乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过5050。

现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度。

给出每段小木棍的长度,编程帮他找出原始木棍的最小可能长度。

搜索+剪枝

先贴一个70分的代码:

#include<bits/stdc++.h>

#define N 1010
using namespace std; int n,a[],tot,sum,sh[N]; bool vis[N],flg,pvis[]; void scz(int k){
for(int i=;i<=k;i++) pvis[sh[i]]=;
} void dfs(int k,int l,int L){
if(l==L){
++sum;
if(sum*L==a[]) flg=;
scz(k-);
return;
}
for(int i=;i<=tot;i++){
if(!vis[i]&&l+a[i]<=L&&!pvis[i]){
vis[i]=;sh[k]=i;
dfs(k+,l+a[i],L);
vis[i]=;
}
}
} int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++){
scanf("%d",&a[++tot]);
if(a[tot]>) --tot;
// a[0]+=a[tot];
a[n+]=max(a[n+],a[tot]);
}
for(int i=;i<=tot;i++)
a[]+=a[i];
// ,printf("%d\n",a[i]);
// printf("%d\n",a[0]); for(int i=a[n+];i<=a[];i++){
memset(pvis,,sizeof(pvis));
if(a[]%i==){
sum=;
dfs(,,i);
if(flg){
printf("%d\n",i);
break;
}
}
}
return ;
}

剪枝大法好

#include<bits/stdc++.h>

#define N 1010
using namespace std; int n,a[],tot,sum,L,last; bool vis[N]; bool dfs(int R,int M){//还剩下的木棍,需要拼凑的木棍长度
if(R==&&M==)
return true;
if(M==)
M=L;
int st=;
if(M!=L)
st=last+;//剪枝4,从下一根更短的进行尝试 ,而不是从头开始
for(int i=st;i<=tot;i++){
if(!vis[i]&&a[i]<=M){
if(i>&&vis[i-]==false&&a[i]==a[i-]){
continue;
}//剪枝1,如果上一个没被选中且当前这一个与上一个长度相等
vis[i]=;last=i;
if(dfs(R-,M-a[i])) return true;
else vis[i]=;
if(M==L||a[i]==M)
return false;//剪枝2,如果第一根木棍不能更新,那么就永远不能更新
//剪枝3 如果当前木棍在==M的情况下不能成功,那就不可能成功
}
}
return false;
} bool cmp(int x,int y) {
return x>y;
} int main() {
scanf("%d",&n);
for(int i=; i<=n; i++) {
scanf("%d",&a[++tot]);
if(a[tot]>) --tot;
a[n+]=max(a[n+],a[tot]);
}
for(int i=; i<=tot; i++)
a[]+=a[i];
sort(a+,a++tot,cmp); for( L=a[n+]; L<=a[]/; L++) {
memset(vis,,sizeof(vis));
if(a[]%L) continue;
if(dfs(tot,L)){
printf("%d\n",L);
break;
}
}
if(L>a[]/) printf("%d\n",a[]);
return ;
}

剪枝方法总结:

1) 要选择合适的搜索顺序 如果一个任务分为 A, B, C…..等步骤(先后次序无关), 要优先尝试可能性少的步骤

2) 要发现表面上不同,实质相同的重复状态,避免重复的搜索

3) 要根据实际问题发掘剪枝方案

洛谷——P1120 小木棍 [数据加强版]的更多相关文章

  1. 洛谷 P1120 小木棍 [数据加强版]解题报告

    P1120 小木棍 [数据加强版] 题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它 ...

  2. 洛谷 P1120 小木棍 [数据加强版]

    P1120 小木棍 [数据加强版] 题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它 ...

  3. 洛谷—— P1120 小木棍 [数据加强版]

    https://www.luogu.org/problem/show?pid=1120 题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接 ...

  4. [洛谷P1120]小木棍 [数据加强版]

    题目大意:有一些同样长的木棍,被切割成几段(长$\leqslant$50).给出每段小木棍的长度,找出原始木棍的最小可能长度. 题解:dfs C++ Code: #include<cstdio& ...

  5. 一本通&&洛谷——P1120 小木棍 [数据加强版]——题解

    题目传送 一道特别毒瘤能提醒人不要忘记剪枝的题. 首先不要忘了管理员的话.忘把长度大于50的木棍过滤掉真的坑了不少人(包括我). 显然是一道DFS题 .考虑剪枝. 找找搜索要面临的维度.状态:原始木棍 ...

  6. 洛谷P1120 小木棍 [数据加强版]搜索

    玄学剪支,正好复习一下搜索 感觉搜索题的套路就是先把整体框架打出来,然后再一步一步优化剪枝 1.从maxv到sumv/2枚举长度(想一想,为什么) 2. 开一个桶,从大到小开始枚举 3. 在搜索中,枚 ...

  7. P1120 小木棍 [数据加强版] 回溯法 终极剪枝

    题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过5050. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度. 给出每段小木棍的长度 ...

  8. P1120 小木棍 [数据加强版]

    题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度. 给出每段小木棍的长度,编 ...

  9. P1120 小木棍 [数据加强版](poj 1011)

    题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度. 给出每段小木棍的长度,编 ...

随机推荐

  1. java Bean及其使用

    1 getter/setter方法 java例子: public class student { private String name; public String getName() { retu ...

  2. 视频生成 量产 win 转 linux ffmpeg linux 安装 对批量视频的尽可能短时间生成

    环境准备 Welcome to aliyun Elastic Compute Service! [root@mytest ~]# pip install baidu-aip Looking in in ...

  3. 在Ubuntu 12.04 LTS下成功访问Windows域共享(mount //192.168.1.102/share -o user=DOMIAN\\user,pass=passwd /mnt)

    Ubuntu 12.04 LTS下成功访问Windows域共享: 1,在命令行模式下 mount //192.168.1.102/share -o user=DOMIAN\\user,pass=pas ...

  4. 洛谷 P1236 算24点

    题目描述 几十年前全世界就流行一种数字游戏,至今仍有人乐此不疲.在中国我们把这种游戏称为"算24点".您作为游戏者将得到4个1~9之间的自然数作为操作数,而您的任务是对这4个操作数 ...

  5. Gamma的完全理解

    Gamma校正 问题:什么是Gamma曲线矫正?Gamma曲线矫正是什么意思?       Gamma曲线是一种特殊的色调曲线,当Gamma值等于1的时候,曲线为与坐标轴成45°的直线,这个时候表示输 ...

  6. E20171123-sl

    conform  vi. 符合; 遵照; 适应环境;               vi. 符合; 遵照; 适应环境;                 adj. 一致的; 顺从的; investigat ...

  7. bzoj 4756: [Usaco2017 Jan]Promotion Counting【dfs+树状数组】

    思路还是挺好玩的 首先简单粗暴的想法是dfs然后用离散化权值树状数组维护,但是这样有个问题就是这个全局的权值树状数组里并不一定都是当前点子树里的 第一反应是改树状数组,但是显然不太现实,但是可以这样想 ...

  8. bzoj 1689: [Usaco2005 Open] Muddy roads 泥泞的路【贪心】

    按左端点排序,贪心的选即可 #include<iostream> #include<cstdio> #include<algorithm> using namesp ...

  9. 洛谷 P1462 通往奥格瑞玛的道路(spfa+二分搜索)(4boy)

    原题:http://www.luogu.org/problem/show?pid=1462#sub 4boy: 大意:给出n个城市,有m条路,每经过一个城市都要交钱,每经过一条道路都要扣HP,有HP上 ...

  10. Notepad++安装插件

    https://sourceforge.net/projects/npp-plugins/files/ 下载完插件后,通过notepad++的设置>>>>导入>>& ...