zoukankan      html  css  js  c++  java
  • Evanyou Blog 彩带

      题目传送门

    题目描述
    乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50。

    现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度。

    给出每段小木棍的长度,编程帮他找出原始木棍的最小可能长度。

    输入输出格式
    输入格式:
    输入文件共有二行。

    第一行为一个单独的整数N表示砍过以后的小木棍的总数,其中N≤65

    (管理员注:要把超过50的长度自觉过滤掉,坑了很多人了!)

    第二行为N个用空个隔开的正整数,表示N根小木棍的长度。

    输出格式:
    输出文件仅一行,表示要求的原始木棍的最小可能长度

    输入输出样例
    输入样例#1:
    9
    5 2 1 5 2 1 5 2 1
    输出样例#1:
    6
    说明
    2017/08/05

    数据时限修改:

    -#17 #20 #22 #27 四组数据时限500ms

    -#21 #24 #28 #29 #30五组数据时限1000ms

    其他时限改为200ms(请放心食用)


      分析:CL大佬讲课的时候讲到了这题,于是就来做一下。但是讲的时候没听,于是做的时候遇到了瓶颈,还是参考了five20大佬的博客。确定了搜索的思路,那么要考虑的就是如何剪枝,这题真的是一道练习搜索剪枝的绝(e)世(xin)好(gui)题。总共需要用到一下几种剪枝:

      1,搜索范围:很显然,答案肯定是在[maxn,sum]内,maxn为给定木棍的最大长度,sum为给定木棍长度之和,同时正确答案一定能被sum整除,所以搜的时候范围就确定在maxn到sum/2之间能把sum整除的所有整数。如果在该范围内均不满足,那么答案就是sum。

      2,搜索顺序:由上面得出的范围可知,从大到小搜索更优,而且根据题目可知,木棍长度<=50,那么也不需要快排了,直接桶排,记录每种长度的木棍的数目即可。

      3,如果搜索过程中已经使用过长度为x的木棍,那么下一层搜索直接从x开始从大到小搜,因为显然此刻使用了x那么比x长的都已经不可行了。

      4,如果某次搜索时如果当前长度为0或当前长度加选择木棍的长度等于目标长度,那么搜完以后直接break,因为是从大到小枚举,因此再小的木棍就不能达到目标长度了。(这个优化可能这么说并不太好理解,结合代码应该就好懂了)

      Code:

      

    //It is made by HolseLee on 19th Apr 2018
    //Luogu.org P1120
    #include<bits/stdc++.h>
    using namespace std;
    const int N=101;
    int n,num[N],sum,cnt;
    int maxn=0,minn=N;
    inline void dfs(int tar,int now,int len,int m)
    {
      if(!tar){printf("%d",len);exit(0);}
      if(now==len){
        dfs(tar-1,0,len,maxn);
        return;}
      for(int i=m;i>=minn;i--){
        if(now+i<=len&&num[i]){
          num[i]--;
          dfs(tar,now+i,len,i);
          num[i]++;
          if(!now||now+i==len)
        break;}
      }
    }
    int main()
    {
      ios::sync_with_stdio(false);
      cin>>n;int x;
      for(int i=1;i<=n;i++){
        cin>>x;
        if(x<=50){
          num[x]++;cnt++;
          maxn=max(maxn,x);
          minn=min(minn,x);
          sum+=x;}
      }
      for(int i=maxn;i<=sum/2;i++){
        if(sum%i==0)dfs(sum/i,0,i,maxn);
      }
      printf("%d",sum);
      return 0;
    }
  • 相关阅读:
    leetcode701. Insert into a Binary Search Tree
    leetcode 958. Check Completeness of a Binary Tree 判断是否是完全二叉树 、222. Count Complete Tree Nodes
    leetcode 110. Balanced Binary Tree
    leetcode 104. Maximum Depth of Binary Tree 111. Minimum Depth of Binary Tree
    二叉树
    leetcode 124. Binary Tree Maximum Path Sum 、543. Diameter of Binary Tree(直径)
    5. Longest Palindromic Substring
    128. Longest Consecutive Sequence
    Mac OS下Android Studio的Java not found问题,androidfound
    安卓 AsyncHttpClient
  • 原文地址:https://www.cnblogs.com/cytus/p/8886465.html
Copyright © 2011-2022 走看看