1011Sticks

改了很久还是超时,没有办法

做dfs,我喜欢定义一些全局变量,其实这样在应用dfs()时,会导致一些不必要的赋值,变之前,要改动,变后还得恢复现场,这就很容易出错了

从人家的代码,

while(sticks[i]==sticks[i+1])i++;
这一句可以节省时间,当然这是单单这道题目而言的,而且我一开始是打算每次调用dfs时都检查一下是否所有的set都是1,即都是应用过的,结果看了他的代码发现,其实可以用一个变量s来记录已经结合了多少段,毕竟当每段的长度选好了,总的段数是固定的

这是人家的正确代码,解答得很详细了

#include <iostream>
#include <string.h>
#include <stdio.h>
#include <algorithm>

using namespace std;
int sticks[65],n,sum,num,l;//l最小的与木棒的长度 num:圆木棒的个数  sum:圆木棒的总长度
bool mark[65];
bool cmp(int a,int b)
{
    return a>b;
}

//s:已经组成的小木棒的个数,le:当前搜索时正在组成的小木条的长度。pos:要组合的小木条的下标位置
bool dfs(int s,int le,int pos)
{
    int i;
    bool sign = (le == 0?true:false);
    if(s==num)return true;
    for(i = pos + 1;i < n;i++)
    {
        if(mark[i])continue;//如果这个小木棒组合过则从下一个开始
        if(le + sticks[i]==l)//如果组合刚好组成l长度的木棒那么就要组合下一根木棒了即第s+1根
        {
            mark[i] = true;
            if(dfs(s+1,0,-1))//第s根已经组合成功了组合下一根
            return true;
            mark[i] = false;
            return false;//如果组合失败了那么就要返回false 而且这个木棒的状态应还原为没组合过
        }
        else if(le + sticks[i]<l)
        //如果组合当前这根后长度仍然小于l那么从i开始往下找继续组合第S根木棒
        {
            mark[i] = true;
            if(dfs(s,le+sticks[i],i))//如果可以组成就返回true
            return true;
            mark[i] = false;
            if(sign)return false;
            while(sticks[i]==sticks[i+1])i++;
        }
    }
    return false;
}

int main()
{
    while(scanf("%d",&n)!=EOF,n)
    {
        sum = 0;

        for(int i = 0; i < n; i++)
        {
            scanf("%d",&sticks[i]);
            sum += sticks[i];
        }
        sort(sticks,sticks+n,cmp);//将木棒从大到小排序
        for(l = sticks[0]; l <= sum; l++)//从最大的开始搜索
        {
            if(sum%l==0)//如果该长度可以被整除那么可能是结果,否则继续
            {
                num = sum/l;//num:记录该情况下可以组成的木棒的数目。
                memset(mark,false,sizeof(mark));//每种情况都要进行初始化,把所有的木棒的使用状态设为false
                if(dfs(1,0,-1))//当返回true时说明搜索成功了,可以组成该长度木条
                {
                    printf("%d
",l);
                    break;
                }
            }
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/dowson/p/3394366.html