[題解]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. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度. 给出每段小木棍的长度,编 ...
随机推荐
- 需要注意的一些Mysql语句
1. 日期处理函数:date_format() select COUNT(*) from (SELECT SERIAL_NO, APPLY_SERIAL_NO, FLAG, PAY_DATE, SEQ ...
- [haoi2008]玩具命名
某人有一套玩具,并想法给玩具命名.首先他选择WING四个字母中的任意一个字母作为玩具的基本名字.然后他会根据自己的喜好,将名字中任意一个字母用“WING”中任意两个字母代替,使得自己的名字能够扩充得很 ...
- git多人协作冲突解决方法
http://www.trinea.cn/dev-tools/git-skill/ http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361 ...
- JavaWeb项目里面的路径获取方法总结
仅为资源搬运,个人还未充分理解... request.getRealPath不推荐使用request.getRealPath("") 这个方法已经不推荐使用了 request.ge ...
- 操作Zookeeper
可以通过图形化界面进行操作使用的工具是 zookeeper-dev-ZooInspector.jar 连接到我的zk之后: 1.Java操作zk 依赖: <dependency> < ...
- FindBugs规则整理
http://blog.csdn.net/jdsjlzx/article/details/21472253/ 配置FindBugs和常见FindBugs错误 http://blog.csdn.net/ ...
- zabbix数据库创建初始化
MariaDB [(none)]> create database zabbix character set utf8; MariaDB [(none)]> grant all privi ...
- 「LuoguP3796」 【模板】AC自动机(加强版)
题目描述 有N个由小写字母组成的模式串以及一个文本串T.每个模式串可能会在文本串中出现多次.你需要找出哪些模式串在文本串T中出现的次数最多. 输入输出格式 输入格式: 输入含多组数据. 每组数据的第一 ...
- MT8735A平台配置MT6630
1. codegen配置 2. ProjectConfig CUSTOM_HAL_ANT = mt6630_ant_m1 CUSTOM_HAL_COMBO = mt6630 MTK_BT_CHIP = ...
- 安装ubuntu16.04之后无法关机和重启
这个问题是由于NVIDA驱动导致的,查询显卡型号,安装对应版本的驱动就可以解决此问题.ubuntu16.04 NVIDIA 驱动安装