洛谷 P1120 小木棍
排序后枚举原来木棍的长度,然后去搜索,搜索成功则结束程序。
搜索不成功的则尽早退出搜索。
剪枝:
顺序剪枝:对木棍排序,然后先用大的后用小的
(若a=b+c,则如果既可以使用a也可以使用b+c那么使用a,因为b和c可能会在后面单独被用到
而且,先用大的去拼可以更快的排除错误选项)
等效性剪枝:当前状态下,长度为a[i]的用过不行,那就换一个长度不要用等长度的a[i+1]去尝试了
可行性剪枝 :如果使用当前木棍正好拼成H但上面没有return 则该H不行
h==0是对第一次搜索一定要能第一根木棍 才合法
#include<iostream>
#include<queue>
#include<cstdio>
#include<algorithm>
#include<math.h>
#include<string.h>
using namespace std;
int n,a[69],cnt,c,m;
int ans=0,vis[70];
int tot,maxn;
bool cmp(const int x,const int y) { return x>y;}
//当前高度 上一个木棍编号 还需拼几根木棍 目标长度
void dfs(int h,int last,int sum,int H)
{
if(sum==0)
{
printf("%d",ans);
exit(0);
}
for(int i=last+1;i<=n;i++)
if(!vis[i])
{
if(h+a[i] < H)
{
vis[i]=1;
dfs(h+a[i],i,sum,H);
vis[i]=0;
}
if(h+a[i] == H)
{
vis[i]=1;
dfs(0,0,sum-1,H);
vis[i]=0;
}
if(h+a[i]==H || h==0) break;
// /可行性剪枝 如果使用当前木棍正好拼成H但上面没有return 则该H不行
//可行性剪枝 h==0是对第一次搜索一定要能第一根木棍 才合法
while( a[i+1] == a[i]) i++;
//排除等效剪枝,长度为a[i]的用过了就不要再去用了
}
return ;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&c);
a[i]=c;
tot+=c;
maxn=max(maxn,c);
}
sort(a+1,a+1+n,cmp);//顺序剪枝
int sum=0;
for(int i=maxn;i<=tot;i++)//i每根长度,tot/i,根数
{
if(tot%i) continue;
sum=tot/i;ans=i;
dfs(0,0,sum,i);
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
2017-07-24 数字(number)
2017-07-24 寻找最美的你(select)
2017-07-24 木棍
2017-07-24 lowbit