zoukankan      html  css  js  c++  java
  • P1120 小木棍 [数据加强版]

    https://www.luogu.org/problem/show?pid=1120#sub
    枚举最小长度(从max–>sum),用dfs来判断,如果能成功就可以,退出即可。
    dfs中有好多高深的剪枝!!
    先将长度降序排序,便于剪枝。

    剪枝:
    判断当前的len时
    1).如果在前面已经建造这一根长木棒的一部分的基础上如果这跟小木棒不能成功,那么和它长度相同的一定也不成功。
    2).如果正好这跟小木棒再放上能够建成一根长木棒,而且不成功,那么当前枚举的长木棒len就一定不能成功,return 0;
    3).若木棍X是旧一组的最后一根,旧一组拼完后,发现新一组无法完成,就不需要再枚举比木棍X小的木棍了;即当前枚举的长木棒len就一定不能成功,return 0;

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm> 
    #include<cmath>
    using namespace std;
    int N,a[101],n,sum,maxn;
    int f[101];
    bool cmp(int x,int y){return x>y;} 
    bool dfs(int x,int len,int now,int num)//当前枚举的最小长度--现在已经拼完的长度--现在拼完的根数  
    {
        if(num==sum/len) return 1;
    
        if(now==len)
        if(dfs(1,len,0,num+1)) return 1;
    
        for(int i=x;i<=n;i++)
        if(!f[i]&&now+a[i]<=len)
        {
            f[i]=1;
            if(dfs(i+1,len,now+a[i],num)) return 1;
            f[i]=0;
    
            if(a[i]==len-now||now==0) break;
            while(a[i]==a[i+1]) i++;
        }
        return 0;
    }
    int main()
    {
        scanf("%d",&N);
        for(int i=1;i<=N;i++)
        {
            int x;scanf("%d",&x);
            if(x<=50){
                a[++n]=x,sum+=x;
                maxn=max(maxn,x);
            }
        }
        sort(a+1,a+n+1,cmp);
        for(int i=maxn;i<=sum;i++)
        if(sum%i==0){
            memset(f,0,sizeof(f));
            if(dfs(1,i,0,0)){
                printf("%d
    ",i);
                break;
            }
        }
        return 0;
    }
  • 相关阅读:
    Java集合 使用Map
    Java集合 编写equals方法
    yiyou本地安装出现版本问题
    网站地图制作
    SEO小爬虫工具文章排版
    知名企业招聘技术员题库
    测试上网速度
    邮件传输协议软件
    JSONP跨域问题
    织梦搬家
  • 原文地址:https://www.cnblogs.com/dfsac/p/7587861.html
Copyright © 2011-2022 走看看