zoukankan      html  css  js  c++  java
  • poj1011Sticks

    传说中的poj必做50题之中的一个……

    这是个传说中的搜索,

    一開始以为,

    仅仅要棒子加起来等于如果的原始长度,

    那么这几根选择的棒子就不用管了,

    结果卡在第一个例子……

    看了一下,发现,

    代码把1,2,1,2合成一个棒子,

    这样其它就凑不成3根长度为6的棒子了,

    写了半天,发现思路错了,

    这个问题不知道怎样解决。

    參考了下面地址的结题报告:

    http://blog.csdn.net/lyy289065406/article/details/6647960

    找到了一个解决的方法,

    就是当合成了一个新的棒子的时候,

    就又一次从第一个棒子開始枚举,

    用没实用过的棒子,開始合成新的棒子。

    写好代码之后,各种TLE……

    于是又參考了上面那个解题报告,

    找了个剪枝的办法,

    就是假设碰到用某个棒子为第一个棒子合成新棒子

    的时候,无法得到我想要的那种棒子,

    就直接退栈并返回一个0表示这样不行,

    写好之后,结果还是TLE,

    于是继续剪了个枝

    就是一開始给棒子递增排个序,

    然后假设在合成棒子的中途发现

    合成失败,用这根棒子得不到想要的那种棒子,

    就把这个棒子标记一下,

    假设在这次合成中再次碰到一样长度的棒子,

    就直接舍弃。

    又写好了……还是TLE。。。

    我就不明确了……

    再TLE,我真的没办法了。

    又參考了结题报告,

    发现给棒子递减排序就能够,

    想了一下为毛,

    是这种,由于优先增加长度较长的棒子,

    更easy在比較少的次数里合成想要的那种棒子。

    我的代码例如以下,欢迎讨论:

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int stick[74],num_stk,sum_len;
    bool used[74];
    bool cmp(int a,int b)
    {
    	return a>b;
    }
    void init()
    {
    	int i;
    	sum_len=0;
    	for(i=0;i<num_stk;i++)
    	{
    		scanf("%d",&stick[i]);
    		sum_len+=stick[i];
    	}
    }
    bool dfs(int s,int nlen,int nnum,int olen)
    {
    	int i,x=-1;
    	if(nnum==num_stk)
    		return 1;
    	for(i=s;i<num_stk;i++)
    	{
    		if(used[i]||stick[i]==x||nlen+stick[i]>olen)
    			continue;
    		used[i]=1;
    		if(nlen+stick[i]<olen)
    		{
    			if(dfs(i+1,nlen+stick[i],nnum+1,olen))
    				return 1;
    		}
    		else
    		{
    			if(dfs(0,0,nnum+1,olen))
    				return 1;
    		}
    		x=stick[i];
    		used[i]=0;
    		if(nlen==0)
    			return 0;
    	}
    	return 0;
    }
    void work()
    {
    	int i;
    	memset(used,0,sizeof(used));
    	sort(stick,stick+num_stk,cmp);
    	for(i=stick[0];i+i<=sum_len;i++)
    	{
    		if(sum_len%i==0&&dfs(0,0,0,i))
    		{
    			printf("%d
    ",i);
    			return;
    		}
    	}
    	printf("%d
    ",sum_len);
    }
    int main()
    {
    	while(scanf("%d",&num_stk)&&num_stk!=0)
    	{
    		init();
    		work();
    	}
    }

  • 相关阅读:
    render 动态增减表单项校验 小结
    面试题总结2
    禁止蒙层底部页面跟随滚动
    前端面试题总结1
    ||与??的区别,??非空运算符,??=非空赋值运算符 ??.链判断运算符 Object.defineProperty 与Proxy的区别
    chrome 代码调试实用小技巧
    Ubuntu安装ibmmq
    Python语言规范之Pylint的使用
    Python发送SMTP邮件指南
    快看那个运维妹子在学算法【二分查找】
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4203855.html
Copyright © 2011-2022 走看看