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

    https://www.luogu.org/problem/show?pid=1120

    题目描述

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

    从大到小排序(方便剪枝,小木棒拼接更灵活),搜索 当前未拼得的原木棒的长度,已经凑出的原木棒根数,当前拼出的根数。

     1 #include <algorithm>
     2 #include <cstdio>
     3 
     4 const int N(66);
     5 int n,len[N],tot,sum,ans;
     6 bool cmp(int a,int b)
     7 {
     8     return a>b;
     9 }
    10 
    11 bool vis[N];
    12 bool DFS(int nowlenth,int cnt,int num)
    13 {
    14     if(cnt==tot) return 1;
    15     if(!nowlenth)
    16         if(DFS(ans,cnt+1,1)) return 1;
    17     for(int i=num; i<=n; ++i)
    18     {
    19         if(vis[i]||len[i]>nowlenth) continue;
    20         vis[i]=1;
    21         if(DFS(nowlenth-len[i],cnt,i+1)) return 1;
    22         vis[i]=0;
    23         if(len[i]==nowlenth||nowlenth==ans) break;
    24         //如果当前长度不能拼出下一根木棒,最大的失效则没有可以全部拼出的情况 
    25         for( ;len[i+1]==len[i]; ) ++i;//剪去等长的木棒 
    26     }
    27     return 0;
    28 }
    29 
    30 inline void read(int &x)
    31 {
    32     x=0; register char ch=getchar();
    33     for(;ch>'9'||ch<'0';) ch=getchar();
    34     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
    35 }
    36 
    37 int AC()
    38 {
    39     read(n);
    40     for(int i=1,x; i<=n; ++i)
    41     {
    42         read(x);
    43         if(x>50)
    44         {
    45             i--;n--;
    46             continue;
    47         }
    48         len[i]=x,sum+=x;
    49     }
    50     std::sort(len+1,len+n+1,cmp);
    51     for(ans=len[1]; ans<=sum; ++ans)
    52     {
    53         if(sum%ans) continue;
    54         tot=sum/ans;
    55         if(DFS(ans,0,1))
    56         {
    57             printf("%d
    ",ans);
    58             return 0;
    59         }
    60     }
    61     return 0;
    62 }
    63 
    64 int Hope=AC();
    65 int main(){;}
    ——每当你想要放弃的时候,就想想是为了什么才一路坚持到现在。
  • 相关阅读:
    【JZOJ6223】【20190617】互膜
    【JZOJ6225】【20190618】计数
    【JZOJ6226】【20190618】纳什均衡
    【JZOJ6210】【20190612】wsm
    【学习笔记】析合树
    【JZOJ6206】【20190610】二分图边染色
    【loj3123】【CTS2019】重复
    【loj3120】【CTS2019】珍珠
    【loj3119】【CTS2019】随机立方体
    CTS&&APIO2019爆零记
  • 原文地址:https://www.cnblogs.com/Shy-key/p/7481424.html
Copyright © 2011-2022 走看看