北大ACM POJ 1011解答报告
这题花了我九牛二虎之力啊,主要考查搜索过程中的剪枝,剪了N多,发现几个重要剪枝,见下面源码分析
Problem: 1011 | | User: absolute |
Memory: 204K | | Time: 16MS |
Language: C++ | | Result: Accepted |
#include <stdio.h>
#include <algorithm>
void POJ1011();
int inputnum;
bool used[64];
int partlen[64];
int main()
{
POJ1011();
return 0;
}
bool searchStick(int needstick,int pos,int leftlen,int sticklen,int start)
{
if(leftlen==0)
{
if(needstick==1)
return true;
start=0;
while(used[start])
{
start++;
}
if(searchStick(needstick-1,start,sticklen,sticklen,start))
return true;
return false;
}
else
{
if(pos>inputnum-1)
return false;
int i;
for(i=pos;i<inputnum;++i)
{
if(used[i])
continue;
if(partlen[i]>leftlen)
continue;
if(partlen[i]==partlen[i-1]&&!used[i-1])
continue;
used[i] = true;
if(searchStick(needstick,i+1,leftlen-partlen[i],sticklen,start))
return true;
used[i] = false;
if(partlen[i]==leftlen)
return false;
if(i==start)
return false;
}
return false;
}
}
//比较函数最好自己实现
bool cmp(int a,int b)
{
return a>b;
}
void POJ1011()
{
int i;
scanf("%d",&inputnum);
while(inputnum!=0)
{
int maxnum,len,totallen=0,maxpart=0;
memset(used,0,sizeof(used));
for(i=0;i<inputnum;i++)
{
scanf("%d",partlen+i);
totallen+=partlen[i];
}
std::sort(partlen,partlen+inputnum,cmp);
maxnum = 64>totallen/partlen[0]?totallen/partlen[0]:64;
int num;
for(num = maxnum;num>0;--num)
{
if(totallen%num==0)
{
len = totallen/num;
if(searchStick(num,0,len,len,0))
{
printf("%d\n",len);
break;
}
}
}
scanf("%d",&inputnum);
}
}
POJ 1011答案源码