[題解]luogu_P1120小木棍(搜索)
2024-08-23 21:26:21
好久以前抄的題解,現在重新抄題解做一下
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);
}
最新文章
- 【分布式】Zookeeper使用--Java API
- Oracle连接数据库的封装类OracleDB
- 使用protractor操作页面元素
- Android Design Principles
- [leetcode 17]Letter Combinations of a Phone Number
- mybatis mapper association collection
- QT 按钮(4种样式)
- WCF学习笔记(一):WCF简介
- 动态加载Layout 与 论Activity、 Window、View的关系
- ASP.NET程序发布流程
- XCL-Charts绘画面积图(AreaChart) 案件1
- Solr集群搭建
- jQuery选择器使用习惯
- zookeeper 启动失败 BindException: Address already in use 或者Error contacting service. It is probably not running
- GC其他:引用标记-清除、复制、标记-整理的说明
- 【带着canvas去流浪】 (3)绘制饼图
- 95%的技术面试必考的JVM知识点都在这,另附加分思路!
- pyquery 库的方法
- 读取html文件,让其中的内容和notepad打开这个html的样子一样。
- Java中static块执行时机