zoukankan      html  css  js  c++  java
  • POJ-1011(sticks,深搜)

    Description

    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.

    Input

    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.

    Output

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

    Sample Input

    9
    5 2 1 5 2 1 5 2 1
    4
    1 2 3 4
    0
    

    Sample Output

    6
    5
    

    分析:

    • 先存大的棍子,对于每一次搜索,关心的状态有三个:现在拼的棍子是第几个,已经拼了多少了,上次拼的那根是序列中的第几根
    • 如果拼当前棍子的时候,拼了一个长度为a的棍子,发现失败了,那么之后就不用再尝试长度为a的棍子了
    • 如果现在要拼的棍子长度为0,然后发现有一个棍子试图去拼然后失败了,那么这条路子就是错的,因为最终肯定不会全部拼完整,
    • 同理,如果刚好拼好一根棍子,发现接下来再拼失败了,那么接下来也没办法成功拼完整的。
    int a[100],v[100],n,cnt,len;
    
    bool cmp(int a,int b)
    {
    	return a>b;
    }
    bool dfs(int stick,int cab,int last)
    {
    	if(stick == cnt+1)
    		return true;
    	if(cab == len)
    		return dfs(stick+1,0,1);//这里第一次忘记return了,好坑
    	int fail = 0;
    	for(int i=last;i<=n;i++)
    	{
    		if(!v[i]&&cab+a[i]<=len&&fail!=a[i])
    		{
    			v[i] = 1;		if(dfs(stick,cab+a[i],i+1))
    				return true;
    			fail = a[i];
    			v[i] = 0;
    		    //如上述最后两条所说
    		    if(cab==0||cab+a[i]==len)
    				return false;
    		}
    	}
    	return false;
    }
    int main() 
    {
        while(cin>>n,n)
        {
        	int sum = 0,val = 0;
        	for(int i=1;i<=n;i++)
        	{
        		scanf("%d",&a[i]);
        		sum+=a[i];
        		val = max(val,a[i]);
        	}
        	sort(a+1,a+1+n,cmp);
        	for(len = val;len<=sum;len++)
        	{
        		if(sum%len)continue;
        		cnt = sum/len;
        		//cout<<cnt<<endl;
        		memset(v,0,sizeof v);
        		if(dfs(1,0,1))break;
        	}
        	cout<<len<<endl;
        }
        return 0;
    }
    
  • 相关阅读:
    团队作业3--需求改进&系统设计
    需求分析&原型设计
    团队项目作业1-团队展示
    结对编程
    APP案例分析之华为浏览器
    四则运算生成器做法思路
    关于PHP使用GD库生成的验证码无法在别处显示
    第二次课程心得
    两个程序代码
    5.8下午
  • 原文地址:https://www.cnblogs.com/1625--H/p/9488500.html
Copyright © 2011-2022 走看看