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;
    }
  • 相关阅读:
    spring(三):ApplicationContext
    android Xutils dbutils 注解
    android 录音的断点续传
    android 原生dialog对话框
    android asyncTask 详解
    自定义的dialog
    fragment 添加menu
    android baseApplication 基类
    看项目得到info_freeCsdn-01闪屏页面
    开源项目 github
  • 原文地址:https://www.cnblogs.com/dfsac/p/7587861.html
Copyright © 2011-2022 走看看