标签:des style blog http color os io for
Description
Input
Output
Sample Input
9 5 2 1 5 2 1 5 2 1 4 1 2 3 4 0
Sample Output
6 5
Source
此题一共有4种剪枝方案:
1、之前的一根棍子安装失败,之后不尝试所有与其长度相同的棍子
2、若正在替换一整根棍子中的第一根棍子,则返回失败(替换每个整根棍子中的第一根无法扭转失败局面)
3、保证安装上去的棍子顺序为从长到短,之后每次尝试新棍子,只会选择比最近安装上去的棍子更小的棍子
4、若正在替换一整根棍子中的最后一根棍子,则返回失败(替换每个整根棍子中的最后一根无法扭转失败局面)
(一)只采取了1、2剪枝方案的代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAXN 1000
#define cls(array,num) memset(array,num,sizeof(array))
using namespace std;
int n,stick[MAXN],L;
bool bUsed[MAXN]; //标记木棒是否被用过
bool cmp(int a,int b)
{
return a>b;
}
bool DFS(int R,int M) //还有R根木棒,剩余长度为M
{
if(R==0&&M==0) return true; //任务完成
if(M==0) M=L; //一根棍子拼完,开始拼新的一根
for(int i=1;i<=n;i++)
{
if(!bUsed[i-1]&&stick[i]==stick[i-1]) continue; //剪枝1。之前一根木棒与这根木棒长度相同,但之前那根木棒装不上去,跳过
if(bUsed[i]) continue;
if(stick[i]<=M)
{
bUsed[i]=true;
if(DFS(R-1,M-stick[i])) return true;
else
{
bUsed[i]=false;
if(M==L) return false; //剪枝2。在换第一根棍子,这是徒劳的,无论把第一根棍子换成其他任何棍子都将失败,返回false
}
}
}
return false;
}
int main()
{
while(1)
{
cls(stick,0);
int nTotalLen=0;
cin>>n;
if(!n) return 0;
for(int i=1;i<=n;i++)
{
cin>>stick[i];
nTotalLen+=stick[i];
}
sort(stick+1,stick+n+1,cmp);
for(L=stick[n];L<=nTotalLen/2;L++) //L是每个拼好的棍子长度
{
cls(bUsed,0);
if(nTotalLen%L) continue; //L不能整除总长度,显然不行,跳过
if(DFS(n,L))
{
cout<<L<<endl;
break;
}
}
if(L>nTotalLen/2) cout<<nTotalLen<<endl; //如果之前所有长度都不可取,则说明处理后只能拼成一整根棍子
}
return 0;
}(二)采用了4种剪枝方案强剪枝的代码#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAXN 1000
#define cls(array,num) memset(array,num,sizeof(array))
using namespace std;
int n,stick[MAXN],L;
bool bUsed[MAXN]; //标记木棒是否被用过
bool cmp(int a,int b)
{
return a>b;
}
bool DFS(int R,int M) //还有R根木棒,剩余长度为M
{
if(R==0&&M==0) return true; //任务完成
if(M==0) M=L; //一根棍子拼完,开始拼新的一根
for(int i=1;i<=n;i++)
{
if(!bUsed[i-1]&&stick[i]==stick[i-1]) continue; //剪枝1。之前一根木棒与这根木棒长度相同,但之前那根木棒装不上去,跳过
if(bUsed[i]) continue;
if(stick[i]<=M)
{
bUsed[i]=true;
if(DFS(R-1,M-stick[i])) return true;
else
{
bUsed[i]=false;
if(M==L) return false; //剪枝2。在换第一根棍子,这是徒劳的,无论把第一根棍子换成其他任何棍子都将失败,返回false
}
}
}
return false;
}
int main()
{
while(1)
{
cls(stick,0);
int nTotalLen=0;
cin>>n;
if(!n) return 0;
for(int i=1;i<=n;i++)
{
cin>>stick[i];
nTotalLen+=stick[i];
}
sort(stick+1,stick+n+1,cmp);
for(L=stick[n];L<=nTotalLen/2;L++) //L是每个拼好的棍子长度
{
cls(bUsed,0);
if(nTotalLen%L) continue; //L不能整除总长度,显然不行,跳过
if(DFS(n,L))
{
cout<<L<<endl;
break;
}
}
if(L>nTotalLen/2) cout<<nTotalLen<<endl; //如果之前所有长度都不可取,则说明处理后只能拼成一整根棍子
}
return 0;
}两种代码速度差异实在太大,令人惊讶![POJ 1011]Sticks(DFS剪枝),布布扣,bubuko.com
标签:des style blog http color os io for
原文地址:http://blog.csdn.net/qpswwww/article/details/38732131