poj-sticks

参考自:这位博主

描述

George took sticks of the same length and cut them randomly until all parts became at most 50 units long. Now he wants to return sticks to the original state, but he forgot how many sticks he had originally and how long they were originally. Please help him and design a program which computes the smallest possible original length of those sticks. All lengths expressed in units are integers greater than zero.

输入

The input contains blocks of 2 lines. The first line contains the number of sticks parts after cutting, there are at most 64 sticks. The second line contains the lengths of those parts separated by the space. The last line of the file contains zero.

输出

The output should contains the smallest possible length of original sticks, one per line.

样例输入

9
5 2 1 5 2 1 5 2 1
4
1 2 3 4
0
样例输出
6
5

解题思路:

剪枝太复杂......还有点问题......有空再来改.......

---------------------------------------------------------

更,终于把你给AC了,注意几个地方:

(1)回溯部分的几个需要注意的地方已经在注释中给出。

(2)这部分的写法需要注意。如果当前长度的木棍不满足,那么后面一样长度的木棍也一定不会满足。但是改成下面这种写法就直接超时了,估计是加了判断的过程。

        for(j=i+1;j<n;)
{
	 if(a[i]==a[j])
		j++;
}

改成这样就能AC了........

for(j=i+1;j<n&&a[i]==a[j];j++)

具体部分:

# include<stdio.h>
# include<algorithm>
# include<string.h>
using namespace std;
bool cmp(int a,int b)
{
  return a>b;
}

int a[200];
int aver,cnt,flag,n,sum;
int vis[200];
void dfs(int num,int total_len)
{
    if(total_len==aver)
	{
	    total_len=0;
		if(num==cnt)
		{
		  flag=1;
		  return;
		}
	}

	for(int i=0;i<n;i++)
	{
	   if(vis[i]==0&&total_len+a[i]<=aver)
	   {
	      vis[i]=1;
		  if(total_len==0)
			  dfs(num+1,total_len+a[i]);
		  else
			  dfs(num,total_len+a[i]);
                  //这部分回溯是重点
		  vis[i]=0;
		  if(flag==1)//回溯过程中,满足条件则退出
			  return;
		  if(total_len==0)//在回溯过程中,如果当前开始的木棍,有令某一部分total_len为0的情况,而最终却没有满足flag=1,
			  return;//  说明这一组值肯定不满足题意,直接退出
		  int j=i+1;
          for(j=i+1;j<n&&a[j]==a[i];j++);//在回溯过程中,如果当前的木棍长度不满足,那么后面还没有遍历的木棍是一样的长度,
                        i=j-1;           //也一定不会满足,这部分的写法要注意,否则很容易超时
	   }
	}
}
int main()
{
	int i;
	while(scanf("%d",&n)&&n)
	{
	  sum=0;
	  for(i=0;i<n;i++)
	  {
	    scanf("%d",&a[i]);
		sum+=a[i];
	  }
	  sort(a,a+n,cmp);

	  int ans=a[0];
	  for(i=a[0];i<=sum;i++)
	  {
	     if(sum%i==0)
		 {
			memset(vis,0,sizeof(vis));
		    cnt=sum/i;
			aver=i;
			flag=0;
			dfs(0,0);

			if(flag==1)
			{
			  ans=aver;
			  break;
			}
		 }
	  }
	  printf("%d\n",ans);
	}
  return 0;
}

猜你喜欢

转载自blog.csdn.net/zhuixun_/article/details/80200820