[Luogu P1120]小木棍·加强版

#\(\mathcal{Description}\)

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

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

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

#\(\mathcal{Solution}\)

\(hhhh\)这题可真是毒瘤啊\(qwq\)

首先我们先考虑如何\(dfs\),即\(dfs\)时的状态:

1、摆好了几根 2、当前这根还剩的长度 3、当前\(dfs\)是要从哪一根开始摆。

好的,这样会\(T\)飞,所以我们考虑剪枝。

·由于是要全部用光,所以长度一定是总长度的某个因子;而又因为每根木棍至少满足\(\leq\)原始长度,所以我们可以在全部的因子里面二分出一个下界,那么就是这样

    for(i = 1; i <= N; i ++){
        scanf("%d", &a) ;if(a > 50) continue ;
        w[++ cnt] = a, tot += w[cnt], maxn = max(maxn, w[cnt]) ;
    }
    s = sqrt(tot) ;
    for(i = 1; i <= s; i ++) if(!(tot % i)) base[++ total] = i, base[++ total] = tot / i;
    sort(w + 1, w + cnt + 1, cmp) ;
    base[++ total] = tot ; sort(base + 1, base + total + 1) ;
    pos = lower_bound(base + 1, base + total + 1, maxn) - base ;

·但这还不够,我们可以考虑从大到小枚举木棍,因为这样会减少很多无用状态。\(emmm\)写在上面的代码里了。

然而还是\(T\),于是就去瞅了几眼题解,发现在\(dfs\)里面还有很多小优化,比如长度的单调性决定了我们可以舍弃部分状态, 比如如果当前的长度最大都不行,或者已经要开始下一根木棍,那么就直接\(break\).

真是个玛丽题啊\(qwq\)

转载于:https://www.cnblogs.com/pks-t/p/9404967.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值