zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    Stopping User Manager for UID 121” error
    IDEA——如何再次开启ESLint
    堆排序
    akka-typed(10)
    微慕WordPress小程序专业版v3.0发布
    微慕WordPress小程序增强版v2.0发布
    微慕WordPress小程序开源版v3.6发布
    微慕小程序开源版A标签优化说明
    微信小程序开放「分享到朋友圈」功能
    微信小程序直播安装和开发指南
  • 原文地址:https://www.cnblogs.com/dowson/p/3394366.html
Copyright © 2011-2022 走看看