[題解]luogu_P1120小木棍(搜索)
好久以前抄的題解,現在重新抄題解做一下
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小木棍(搜索)的更多相关文章
- 洛谷P1120 小木棍 [搜索]
题目传送门 题目描述乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度. 给出每段小木棍 ...
- 【题解】洛谷P1120 小木棍(搜索+剪枝+卡常)
洛谷P1120:https://www.luogu.org/problemnew/show/P1120 思路 明显是搜索题嘛 但是这数据增强不是一星半点呐 我们需要N多的剪枝 PS:需要先删去超出50 ...
- 洛谷P1120 小木棍 [数据加强版](搜索)
洛谷P1120 小木棍 [数据加强版] 搜索+剪枝 [剪枝操作]:若某组拼接不成立,且此时 已拼接的长度为0 或 当前已拼接的长度与刚才枚举的长度之和为最终枚举的答案时,则可直接跳出循环.因为此时继续 ...
- 洛谷P1120 小木棍
洛谷1120 小木棍 题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长 ...
- P1120 小木棍 [数据加强版] 回溯法 终极剪枝
题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过5050. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度. 给出每段小木棍的长度 ...
- 洛谷 P1120 小木棍 [数据加强版]解题报告
P1120 小木棍 [数据加强版] 题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它 ...
- 题解 P1120 【小木棍 [数据加强版]】
题面 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度. 给出每段小木棍的长度,编程帮 ...
- P1120 小木棍 [数据加强版]
题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度. 给出每段小木棍的长度,编 ...
- P1120 小木棍 [数据加强版](poj 1011)
题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度. 给出每段小木棍的长度,编 ...
随机推荐
- const与define应用上该怎么取舍
const与define应用上该怎么取舍 #define WYB 100; const float WYB = 100; define是在预编译的时候展开替换的,const是编译运行阶段使用 defi ...
- [CPP - STL] swap技巧
最近在看<Effective STL>,[条款17:使用“交换技巧”修整过剩容量]中提到容器的成函数void swap(container& from),即实现容器对象与from对 ...
- Double.valueOf()与Double.parseDouble()两者的区别
写代码用到这两个方法,不知道有什么区别,看一下源码: Double.parseDouble(String str) public static double parseDouble(String s) ...
- jquery特效(7)—弹出遮罩层且内容居中
上周写了几个小特效,其中有个点击按钮弹出遮罩层的特效,下面来看最终实现的效果: 由于是测试的程序,所以我未加关闭的按钮. 一.主体程序 <!DOCTYPE html> <html&g ...
- 人生苦短之Python枚举类型enum
枚举类型enum是比较重要的一个数据类型,它是一种数据类型而不是数据结构,我们通常将一组常用的常数声明成枚举类型方便后续的使用.当一个变量有几种可能的取值的时候,我们将它定义为枚举类型.在Python ...
- android vector pathData探究,几分钟绘制自己的vectordrawable
之前经常看到一些酷酷的图标效果, 深入进去发现不是直接用的图片, 而是一些以Vector标签开头的xml文件, 于是就看到了如下代码: <vector xmlns:android="h ...
- C++中map容器的说明和使用技巧
C++中map容器提供一个键值对容器,map与multimap差别仅仅在于multiple允许一个键对应多个值. 一.map的说明 1 头文件 #include <map> 2 定义 ma ...
- python中字符串的内置方法
这里说的是字符串中的内置方法,毕竟字符串是最常用的操作对象. ['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '_ ...
- myeclipse_JUnit导包问题
第一种方式: MyEclipse创建JUnit单元测试时,在需要测试的代码段前键入“@Test”时,按ctrl和1一般会自动提示JUnit需要导包,但有时会无法提示这个建议,如图所示.该经验教你如何解 ...
- Python框架下django 的并发和多线程
django 的并发能力真的是令人担忧,django本身框架下只有一个线程在处理请求,任何一个请求阻塞,就会影响另一个情感求的响应,尤其是涉及到IO操作时,基于框架下开发的视图的响应并没有对应的开启多 ...