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

    题目描述

    乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过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(请放心食用)

    搜索题,剪枝很重要

    #include <bits/stdc++.h>
    using namespace std;
    #define maxn 100000
    typedef long long ll;
    #define inf 2147483647
    #define ri register int
    
    int n;
    int a[maxn];
    int cnt = 0//真正的总个数
    int tot = 0//真正的总和
    bool used[maxn];
    int x;
    
    bool cmp(int x, int y) { return x > y; }
    
    //G组数,sum当前已装载大小,target每组目标大小,cur当前遍历到的位置
    void dfs(int G, int sum, int target, int cur) {
      if (G == 0) {
        cout << target;
        exit(0);
      }
      if (sum == target) {
        dfs(G - 1, 0, target, 1);
        return;
      }
      if (sum + a[cnt] > target) //最小的都放不进直接pass
        return;
      for (int i = cur; i <= cnt; i++) {
        if (used[i])
          continue;
    //平淡的回溯
        used[i] = true;
        sum += a[i];
        dfs(G, sum, target, i);
        sum -= a[i];
        used[i] = false;
    
        if (sum == 0 || sum + a[i] == target) //如果像这样已经满足目标的都exit不了,那么就没必要继续下去,因为接下来装的数目的也是跟之前一样的
          break;
        while (a[i] == a[i + 1]) //这个数都过不了,相同的数也别想过
          i++;
      }
    }
    
    int main() {
      ios::sync_with_stdio(false);
      // freopen("test.txt", "r", stdin);
      //  freopen("outout.txt","w",stdout);
      cin >> n;
      for (int i = 1; i <= n; i++) {
        cin >> x;
        if (x <= 50) {
          a[++cnt] = x;
          tot += x;
        }
      }
      sort(a + 1, a + 1 + cnt, cmp); //从大到小排次序,能优化不少
      for (int i = a[1]; i <= tot / 2; i++) {
        if (tot % i == 0)
          dfs(tot / i, 0, i, 1);
      }
      cout << tot;
      return 0;
    }
  • 相关阅读:
    JS是单线程的吗?
    JQuery $ $.extend(),$.fn和$.fn.extend javaScript对象、DOM对象和jQuery对象及转换 工具方法(utility)
    JavaScript 操作符 变量
    WEB组件 开发 (未完成 413)
    CSS传统布局之布局模型
    JavaScript 作用域 匿名函数 模仿块级作用域(私有作用域)
    JQuery常用API 核心 效果 JQueryHTML 遍历 Event事件
    JavaScript 属性类型(数据属性 访问器属性)
    CSS居中问题:块级元素和行级元素在水平方向以及垂直方向的居中问题
    javascript 深入浅出 (未完成417)
  • 原文地址:https://www.cnblogs.com/planche/p/8529003.html
Copyright © 2011-2022 走看看