| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
reference code#include <iostream>
#include <cstdlib>
#include <memory>
using namespace std;
int S,L;
int anLength[65],anUsed[65];//记录木棍的长度和访问标记
int nLastStickNo=0;//最近拼上去的那条木棒的下标
int DFS(int,int);
int cmp(const void *a,const void *b)//按降序
{return *(int *)b-*(int *)a;}
int main()
{
while(1)
{
cin>>S;
if(S==0)
break;
int nTotalLen=0;
for(int i=0;i<S;i++)///输入每个棍子长度并记录总共长度
{
cin>>anLength[i];
nTotalLen+=anLength[i];
}
qsort(anLength,S,sizeof(int),cmp);
for(L=anLength[0];L<=nTotalLen/2;L++)//新组成的长度必然大于等于原来中最大的
{
if(nTotalLen%L)//必须保证分成整数几段
continue;
memset(anUsed,0,sizeof(anUsed));//清零
if(DFS(S,L))
{
cout<<L<<endl;
break;
}
}if(L>nTotalLen/2)
{
cout<<nTotalLen<<endl;
}
}
}
int DFS(int nUnusedSticks,int nLeft)//// nLeft表示当前正在拼的棍子和 L比还缺的长度
{
if(nUnusedSticks==0&&nLeft==0)//所有的木棍都用过了并且要拼的木棍的长度是0完成了拼凑返回真值
return true;
if(nLeft==0)////一根刚刚拼完
nLeft=L;//开始拼新的一根
int nStartNo=0;
if(nLeft!=L)//剪枝4
nStartNo=nLastStickNo+1;
for(int i=nStartNo;i<S;i++)
{
if(!anUsed[i]&&anLength[i]<=nLeft)
{
if(i>0)
{
if(anUsed[i-1]==false&&anLength[i]==anLength[i-1])//剪枝 3
//上一根同样长度的木棒为什么还没用?必然是因为刚刚用过,并且发现用了后不行,才将其 anUsed标志置回0
continue;
}
anUsed[i]=1;
nLastStickNo=i;//最近拼上去的那条木棒的下标
if(DFS(nUnusedSticks-1,nLeft-anLength[i]))///表示判断是否已经拼完了一个符合的新木棍
return true;
else
{
anUsed[i]=0;;//说明本次不能用第i根,以后还有用
if(anLength[i]==nLeft||nLeft==L)//剪枝2,1
return false; }
}
}
return false;
}
Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator