zoukankan      html  css  js  c++  java
  • 洛谷P1120-小木棍

    Problem 洛谷P1120-小木棍

    Accept: 3.1k    Submit: 20.9k
    Time Limit: 1000 mSec    Memory Limit : 128MB

    Problem Description

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

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

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

     Input

    共二行。

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

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

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

     Output

     一个数,表示要求的原始木棍的最小可能长度

     

     Sample Input

    9
    5 2 1 5 2 1 5 2 1

     Sample Output

    6
     
    题目链接:https://www.luogu.org/problemnew/show/P1120
     
     
    dfs经典题目,关键在于剪枝。
    首先给木棒排个序,每次尝试加木棒是都是先加目前能加的最大的,因为如果出现如下情况:
    6 = 1+2+3,先用6肯定是优于用1、2、3的,因为小木棒更加灵活。
    一共有三个比较重要的剪枝:
    1.如果当前剩余长度==L,而该次搜索失败了,就代表着当前那根木棒不可能再和别的木棒一起凑出L,自然要return.
    如果left==len[当前],而该次搜索失败了,就不可能再成功了,因为这个left不用当前的木棒去凑,就一定要用短的去凑,即便用短的凑成功了,也就成了6 = 1+2+3的情况,不会再成功了。
    2.如果这根木棒与前一根木棒长度相同,并且前一根搜索失败,那这一根自然不用再搜索了。
    3.由于这个题数据加强,因此多了这个剪枝,感觉这个剪枝和Dinic的当前弧优化很类似,就是dfs多了一个参数:该次搜索从哪一根开始,这个具体操作也很简单,肯定是从上一根加进来的木棒的下一根开始,也就是说那些长的木棒就不再试了,因为这种情况再那些长的木棒的搜索过程中已经尝试过并且失败。
     
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <algorithm>
     6 using namespace std;
     7 
     8 const int maxn = 68;
     9 int n,m;
    10 int L,len[maxn];
    11 bool used[maxn];
    12 
    13 bool cmp(const int &a,const int &b){
    14     return a > b;
    15 }
    16 
    17 bool dfs(int leftm,int sta,int leftl){
    18     if(leftm == 0){
    19         if(leftl == 0) return true;
    20         else return false;
    21     }
    22     if(leftl == 0) sta=1,leftl = L;
    23     for(int i = sta;i <= m;i++){
    24         if(len[i] > leftl || used[i]) continue;
    25         if(i>1 && !used[i-1] && len[i]==len[i-1]) continue;
    26         used[i] = true;
    27         if(dfs(leftm-1,i+1,leftl-len[i])) return true;
    28         used[i] = false;
    29         if(leftl==len[i] || leftl==L) return false;
    30     }
    31     return false;
    32 }
    33 
    34 int main()
    35 {
    36     //freopen("input.txt","r",stdin);
    37     scanf("%d",&n);
    38     m = 0;
    39     int x;
    40     int sum = 0;
    41     for(int i = 0;i < n;i++){
    42         scanf("%d",&x);
    43         if(x <= 50){
    44             len[++m] = x;
    45             sum += x;
    46         }
    47     }
    48     sort(len+1,len+1+m,cmp);
    49     int Max = len[1];
    50     for(L = Max;L <= sum/2;L++){
    51         if(sum%L == 0){
    52             memset(used,false,sizeof(used));
    53             if(dfs(m,1,L)){
    54                 printf("%d
    ",L);
    55                 break;
    56             }
    57         }
    58     }
    59     if(L > sum/2) printf("%d
    ",sum);
    60     return 0;
    61 }
  • 相关阅读:
    SpringMVC-数据处理(三)
    SpringMVC-Controller配置详解(二)
    SpringMVC-简介和执行原理分析(一)
    0913_Python初识及变量
    WebStorm快捷键操作
    纯CSS气泡框实现方法探究
    前端的一些常用DOM和事件归纳
    JS原型与原型链终极详解
    设计趋势:网页设计中的幽灵按钮
    首页焦点图myFocus插件
  • 原文地址:https://www.cnblogs.com/npugen/p/9494348.html
Copyright © 2011-2022 走看看