您的位置:首页 > 理论基础 > 数据结构算法

数据结构(四)递归与回溯——POJ-1011 dfs+剪枝

2018-02-06 09:36 465 查看
题意:给一群剪切好了的木棍,问最短的原木棍长度。

解决思路:一开始自己想,想错了(捂脸),我只是把,给木棍长度进行从大到小的排序,记录总长,从最长的开始拼接,最长的棍在可以找到整除,然后就可以拼接(后来想想真是想的太简单了),然后能后来看了别人写的方法,用的是dfs+剪枝,单单dfs会超时。这个剪枝的办法就看了挺久emmm。

题目链接:poj 1011Sticks

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
//dfs 判断是否ok
int a[100],n,vis[100],L,last;
//dfs+剪枝
//1-对拼接到一半发现不能拼接-保留-寻找
bool dfs(int m,int l)//还剩下棍子和当前拼接剩余长度
{
if(m==0&&l==0) return true;
if(l==0) l=L;
int s=0;
if(l!=L)
s=last+1;//确保从未拼接的部分开始
for(int i=s;i<n;i++)
{
if(!vis[i-1]&&i>0&&a[i]==a[i-1]) continue;//长度相同跳过
if(!vis[i]&&a[i]<=l){
vis[i]=1;
last=i;//1
if(dfs(m-1,l-a[i])) return true;
else{
vis[i]=0;
if(l==L||a[i]==l) return false;//调整该次拼接的拼法
}
}
}
return false;
}
bool cmp(int a,int b){ return a>b; }
int main()
{
while(scanf("%d",&n)!=EOF&&n)
{
memset(a,0,sizeof(a));
int sum=0,l_max=0;
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
sum+=a[i];
if(a[i]>l_max)
l_max=a[i];
}
sort(a,a+n,cmp);//从大到小排序
int i;
for(i=l_max;i<=sum/2;i++)
{
last=0;
memset(vis,0,sizeof(vis));
L=i;
if(sum%i==0)
if(dfs(n,i))
{
printf("%d\n",i);
break;
}
}
if(i>sum/2)
printf("%d\n",sum);
}
return 0;
}


参考
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: