博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
P1120 小木棍 [数据加强版]
阅读量:7170 次
发布时间:2019-06-29

本文共 1365 字,大约阅读时间需要 4 分钟。

神级剪枝。。。


首先这道题有坑点,超过50的木棍不读入。

思想肯定就是爆搜啊!但是直接的爆搜会gg。

接下来是剪枝:

  1. 你当然会聪明地取能够整除的答案来枚举嘛。。

  2. 这些木棍可以从大到小排序,然后从大到小凑木棍。对答案无影响。

  3. 可以记录木棍的最大值和最小值,然后枚举木棍的时候就在这个区间里面弄。

  4. 在每一层dfs中可以记录一个变量p,表示上一次取的木棍是哪根,从p开始枚举到更小会更快。

  5. 若某组拼接不成立,且此时 已拼接的长度为0 或 当前已拼接的长度与刚才枚举的长度之和为最终枚举的答案 时,则可直接跳出循环,因为此时继续枚举其它更小的值时,显然可能情况更少,且同样凑不完。(来自@林则徐)

我抄题解来的。。。希望能够学到。

代码:

#include
#include
#include
const int maxn = 55;int m;int a[maxn];int sum, minv = 19260817, maxv;void dfs(int length, int remain, int temp, int p){ if(remain == 0) { printf("%d\n", length); exit(0); } for(int i = p; i >= minv; i--) { if(a[i] && temp + i <= length) { a[i]--; if(temp + i < length) dfs(length, remain, temp + i, i); else if(temp + i == length) dfs(length, remain - 1, 0, maxv); a[i]++; if(temp == 0 || temp + i == length) break; } }}int main(){ scanf("%d", &m); while(m--) { int temp; scanf("%d", &temp); if(temp > 50) continue; a[temp]++; sum += temp; minv = std::min(minv, temp); maxv = std::max(maxv, temp); } int temp = sum >> 1; for(int i = maxv; i <= temp; i++) { if(sum % i == 0) dfs(i, sum / i, 0, maxv); } printf("%d\n", sum); return 0;}

转载于:https://www.cnblogs.com/Garen-Wang/p/9438547.html

你可能感兴趣的文章
NormalMap
查看>>
java中的注解(一)
查看>>
linux 02 基础命令
查看>>
表单提交中get与post的区别
查看>>
@Transactional注解
查看>>
erlang 时间处理
查看>>
Ubuntu安装pintos
查看>>
Retrofit原理学习
查看>>
hdu Dropping tests 0/1分数规划(二分求值)
查看>>
source命令
查看>>
C、C++混合编程之extern "C"
查看>>
【题解】洪水
查看>>
销傲中国式销售过程管理系统功能概述
查看>>
IDEA 学习笔记之 Java项目开发深入学习(1)
查看>>
重建二叉树 (剑指offer第六题)
查看>>
爬虫基础 pyquery 详解
查看>>
QT creator+OpenCV2.4.2+MinGW 在windows下开发环境配置
查看>>
Allegro PCB Design GXL (legacy) 设置十字大光标
查看>>
数据结构--图的定义和存储结构
查看>>
[C#参考]委托机制
查看>>