【DFS】hdu 1455 Sticks
2013-08-13 20:14
363 查看
http://acm.hdu.edu.cn/showproblem.php?pid=1455
分析:与hdu 1518类似:http://blog.csdn.net/killua_99/article/details/9569709
但明显多了各种剪枝,主要是对题目分析,明白:这些木棒都由相同长度得来,1)可能原长度一定是总和的约数,2)最小可能是从最大的木棒开始计算 etc
测试数据:http://poj.org/showmessage?message_id=172549
再次尝试:
不排序与排序的效率比较:
分析:与hdu 1518类似:http://blog.csdn.net/killua_99/article/details/9569709
但明显多了各种剪枝,主要是对题目分析,明白:这些木棒都由相同长度得来,1)可能原长度一定是总和的约数,2)最小可能是从最大的木棒开始计算 etc
测试数据:http://poj.org/showmessage?message_id=172549
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; const int NM=70; int vis[NM],a[NM]; int c,flag,n; bool comp(int A,int B) { if(A>B) return 1; else return 0; } void DFS(int stick,int ssum,int ans,int k) { if(ans==stick) { ssum++; ans=k=0; //注意把k也更新了 if(ssum==c) flag=1; } if(flag) return; for(int i=k;i<n;i++) { if(!vis[i]&&stick>=ans+a[i]) { ans+=a[i]; vis[i]=1; DFS(stick,ssum,ans,i+1); ans-=a[i]; vis[i]=0; if(k==0||flag) return; /*最重要的剪枝:如果第一根木棒不能形成组合,那么这组数一定不成立*/ while(a[i+1]==a[i]) i++; //防止重复搜索 } } } int main() { int sum,i; //freopen("out.txt","w",stdout);//文件 while(cin>>n&&n) { sum=0; for(i=0;i<n;i++) { scanf("%d",&a[i]); sum+=a[i]; } if(n==1) // { printf("%d\n",sum); continue; } sort(a,a+n,comp); //从较长的木棒开始搜索(因为可能几个较小木棒结合成功,本来它们分别要与较大木棒结合),可以减少回溯次数 for(i=a[0];i<=sum;i++) //好像存在不砍木棒的情况 { if(sum%i!=0) continue; memset(vis,0,sizeof(vis)); c=sum/i; //木棒原先个数 flag=0; DFS(i,0,0,0); //木棒原先长度;个数,长度,第几只木棒 if(flag) { printf("%d\n",i); break; } } } return 0; }
再次尝试:
不排序与排序的效率比较:
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int NM=70; int a[NM],n,temp,num; bool vis[NM],flag; void DFS(int ans,int k,int res) { if(flag) return; if(res==temp){ ans++; res=k=0; } if(ans==num){ flag=true; return; } for(int i=k;i<n;i++){ if(!vis[i] && res+a[i]<=temp){ vis[i]=1; DFS(ans,i+1,res+a[i]); vis[i]=0; if(k==0 || flag) return; while(a[i+1]==a[i]) i++; } } } int main() { int mmax,i,sum; while(scanf("%d",&n)&&n) { sum=mmax=0; for(i=0;i<n;i++) { scanf("%d",&a[i]); sum+=a[i]; if(mmax<a[i]) mmax=a[i]; } flag=false; for(i=mmax;i<=sum;i++) { if(sum%i==0){ num=sum/i;temp=i; memset(vis,0,sizeof(vis)); DFS(0,0,0); if(flag){ printf("%d\n",i); break; } } } } return 0; }
相关文章推荐
- hdu 1455/poj 1011 Sticks(DFS剪枝神题)
- hdu 1455 Sticks(经典DFS)
- hdu 1455 Sticks(dfs+可行性剪枝)
- HDU_1455 && POJ_1011 Sticks (dfs)
- HDU--1455 -- Sticks [DFS] [剪枝优化]
- HDU 1455 Sticks(dfs+强剪枝)
- (step4.3.10)hdu 1455(Sticks——DFS)
- (step4.3.10)hdu 1455(Sticks——DFS)
- HDU 1455 Sticks(DFS,剪枝,原来木棒的至少长度)
- hdu 1455 Sticks 【dfs剪枝】
- HDU-1455 Sticks 经典dfs剪枝
- hdu 1455 Sticks(经典搜索)
- hdoj1455 poj1011 nyoj293 Sticks【DFS+剪枝】
- day3 HDU 1455 Sticks
- HDU 1455 DFS(剪枝优化分析)
- HDU 1455 Sticks
- hdu 1455 ——sticks
- hdu 1455 sticks
- hdu1455 Sticks(搜索+剪枝+剪枝+.....+剪枝)
- hdu--1455--DFS(剪枝之经典)