UVA-307 Sticks (DFS+剪枝)
题目大意:用n根长度未必相等的木棒匹配出最多数量的等长木棒。
题目分析:枚举所有可能的等长木棒的长度,通过DFS的方式逐根匹配,在此过程中要剪枝。先将木棒长度按从大到小排序,也就是说匹配每一根等长木棒时总是优先挑选长的。剪枝方案如下:1. 若第i-1根木棒在当前方案的匹配中没有用到并且length[i]==length[i-1],则第i根木棒也不可能用到;2.若已匹配成功cnt根等长木棒,而第cnt+1根匹配不成功,则要剪枝;3.若在匹配第cnt+1根木棒时,最长的那根木棒stick会第一个被选择,若此时第cnt+1根等长木棒匹配失败,则第cnt+1根等长木棒无须继续匹配,返回第cnt根等长木棒的匹配即可,因为与stick在此次匹配时匹配的可选木棒范围要比以后更大,此次都匹配不成,以后更匹配不成,要重新匹配第cnt根木棒,得以产生新的最长木棒stick’,再由此尝试匹配第cnt+1根等长木棒。
以上三条缺一不可!!!
代码如下:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 int w[100],n; 6 int vis[100]; 7 bool dfs(int cur,int g,int id,int cnt,int sum){ 8 if(g*cnt == sum) 9 return true; 10 for(int i=id;i<n;i++){ 11 if(vis[i]) 12 continue; 13 if(i&& !vis[i-1] && w[i-1] == w[i])///剪枝1 14 continue; 15 if(cur + w[i] == g){ 16 vis[i] = 1; 17 if(dfs(0,g,0,cnt + 1,sum)) 18 return true; 19 vis[i] = 0; 20 return false;///剪枝2 21 } 22 else if (cur + w[i] <g){ 23 vis[i] = 1; 24 if(dfs(cur+w[i],g,i+1,cnt,sum)) 25 return true; 26 vis[i] = 0; 27 if(cur == 0) 28 return false;///剪枝3 29 } 30 } 31 return false; 32 } 33 34 bool cmp(const int &a,const int &b){ 35 return a>b;//sort from up to down 36 } 37 int main(){ 38 while(~scanf("%d",&n)&&n){ 39 int sum = 0; 40 for(int i=0;i<n;i++){ 41 scanf("%d",&w[i]); 42 sum += w[i]; 43 } 44 sort(w,w+n,cmp); 45 int flag=0; 46 // for(int i=0;i<n;i++)printf("%d ",w[i]); 47 for(int i=w[0];i<=sum/2;i++){ 48 if(sum%i==0){ 49 memset(vis,0,sizeof(vis)); 50 if(dfs(0,i,0,1,sum)){ 51 flag =1; 52 printf("%d\n",i); 53 break; 54 } 55 } 56 } 57 if(!flag) 58 printf("%d\n",sum); 59 } 60 return 0; 61 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架