好久以前抄的題解,現在重新抄題解做一下


1.對所有木棍從大到小排序,後用小的比較靈活

2.限制加入的木棍單調遞減,因為先/后用長/短木棍等價,反正就是那兩根

3.預處理出重複木棍的位置,防止重複搜索相同的木棍

4.二分查找下一根小於等於未拼木棍長度的木棍

5.因為是從小到大枚舉原木棍長度,所以第一次找到可行解就是最優的,直接停止

6.如果當前選擇木棍長度等於當前未拼木棍的長度,並且繼續搜索失敗時,就不再搜了

因為如果不用這根拼的話必然要拿更小的幾根木棍拼好當前未拼的長度,

而晚用長木棍早用短木棍只會更加不靈活,一定不會更優(最好情況下也是等價的)

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,a[],v[],nxt[],sum,cnt,len,flag;
void dfs(int k,int las,int res){//k正在拼的木棍編號
//last所用上一節的編號,res當前剩餘未拼長度
int i;
if(!res){//這跟拼完
if(k==m){flag=;return;}//5.全部拼完立即退出
for(i=;i<=cnt;i++)
if(!v[i])break;
v[i]=;
dfs(k+,i,len-a[i]);
v[i]=;
if(flag)return;//6.
}
int l=las+,r=cnt,mid;
while(l<r){//4.二分找下一根木棍
mid=(l+r)>>;
if(a[mid]<=res)r=mid;
else l=mid+;
}
for(int i=l;i<=cnt;i++){
if(!v[i]){
v[i]=;
dfs(k,i,res-a[i]);
v[i]=;
if(flag)return;
if(res==a[i] || res==len)return;//6.上面沒有return,組合失敗,這裡return
i=nxt[i];//3.重複的長度不搜索
if(i==cnt)return;
}
}
}
bool cmp(int a,int b){return a>b;}
int main()
{
scanf("%d",&n);
for(int i=,d;i<=n;i++){
scanf("%d",&d);
if(d<=)a[++cnt]=d,sum+=d;
}
sort(a+,a+cnt+,cmp);//1.
nxt[cnt]=cnt;
for(int i=cnt-;i>=;i--){
if(a[i]==a[i+])nxt[i]=nxt[i+];
else nxt[i]=i;
}
for(len=a[];len<=sum/;len++){
if(sum%len!=)continue;//不能整除跳過(顯然
m=sum/len;//5.
flag=;
v[]=;
dfs(,,len-a[]);
v[]=;
if(flag){
printf("%d\n",len);return ;//5.
}
}
printf("%d\n",sum);
}

[題解]luogu_P1120小木棍(搜索)的更多相关文章

  1. 洛谷P1120 小木棍 [搜索]

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

  2. 【题解】洛谷P1120 小木棍(搜索+剪枝+卡常)

    洛谷P1120:https://www.luogu.org/problemnew/show/P1120 思路 明显是搜索题嘛 但是这数据增强不是一星半点呐 我们需要N多的剪枝 PS:需要先删去超出50 ...

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

    洛谷P1120 小木棍 [数据加强版] 搜索+剪枝 [剪枝操作]:若某组拼接不成立,且此时 已拼接的长度为0 或 当前已拼接的长度与刚才枚举的长度之和为最终枚举的答案时,则可直接跳出循环.因为此时继续 ...

  4. 洛谷P1120 小木棍

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

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

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

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

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

  7. 题解 P1120 【小木棍 [数据加强版]】

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

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

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

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

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

随机推荐

  1. 【C++基础学习】Vector

    代码练习: #include <iostream> #include <vector> using namespace std; int main(){ cout <&l ...

  2. Label标签 自动触发onclick,点击内部的Input

    最近项目遇到了一个bug,点击外层元素会直接触发元素内部的input框.(外层元素用的是label包裹的).找了很久才发现是label标签造成的. label定义和用法: label 标签为 inpu ...

  3. haproxy参数解析

    HAProxy工作于隧道模式,其仅检查每一个连接的第一个请求, 1. option abortonclose #当服务器负载过高时,将自动关闭队列中处理时间较长的连接请求 2. option http ...

  4. iOS 键盘遮挡输入框万能解决方案(多个输入框)

    效果图如下: 思路分析: 代码: 知识点: 问题: 效果图如下: 思路分析: 当我们有很多输入框时,有时候键盘弹出来会遮挡着输入框.我们需要获取输入框和键盘相对于最外层视图的位置来判断是否遮挡,如果遮 ...

  5. cassandra压缩——从文档看,本质上也应该是在做块压缩

    Compression Compression maximizes the storage capacity of Cassandra nodes by reducing the volume of ...

  6. [原创]java对word文档的在线打开

    一.材料准备 百度一下:PageOffice,从官网下载PageOffice for Java.压缩包文件: 二. 实现步骤: 1. 打开“集成文件”目录,拷贝“WEB-INF\lib”目录中的pag ...

  7. nyoj 1279 (河南省第九届ACM比赛 D 题)

    思路:变换一下坐标系新的坐标系就是给定的两条直线,变换之后求 x,y 都严格递增的点的个数的max: 求 x,y 都严格递增的点的个数的max,按照x的从小到大排序,x相同的按照y的从大到小排序然后对 ...

  8. ROM的分类

    转载自:http://www.ic37.com/htm_tech/2012-5/82774_23811.htm ROM(只读存储器)按其内容写入方式,一般分为3种:固定内容ROM:可一次编程PROM: ...

  9. python 基础之第十一天(面向对象)

    #############面向对象##################### 类: In [1]: class MyClass(object): ##用class定义一个类 ...: def psta ...

  10. JAVA THINGKING (一)

    保存数据位置: (1) 寄存器.这是最快的保存区域,因为它位于和其他所有保存方式不同的地方:处理器内部. (2) 堆栈.驻留于常规RAM(随机访问存储器)区域,这是一种特别快.特别有效的数据保存方式, ...