Description

题库链接

有 \(n\) 根木棍,第 \(i\) 根木棍的长度为 \(L_i\) , \(n\) 根木棍依次连结了一起,总共有 \(n-1\) 个连接处。现在允许你最多砍断 \(m\) 个连接处,砍完后 \(n\) 根木棍被分成了很多段,要求满足总长度最大的一段长度最小,并且输出有多少种砍的方法使得总长度最大的一段长度最小。对质数取模。

\(1\leq n\leq 50000,1\leq m\leq \min\{n-1,1000\}\)

Solution

第一问二分,不再赘述。

第二问考虑 \(DP\) 。令 \(f_{i,j}\) 为前 \(i\) 条木棍,划分为 \(j\) 段的方案数。转移我们考虑最后一段怎么分。我们可以预处理出一个数组 \(pre_i\) 表示最后一段最长能分到哪里,显然 \[f_{i,j}=\sum_{k=pre_i}^{i-1}f_{k,j-1}\]

显然这样复杂度是假的。我们可以用前缀和优化,并且珂以记 \(f_{i}\) 为当前枚举到分为 \(j\) 段时,第 \(i\) 条木棍前的方案数。这样直接省去一维。

空间复杂度 \(O(n)\) ;时间复杂度 \(O(nm)\) 。

Code

  1. //It is made by Awson on 2018.3.3
  2. #include <bits/stdc++.h>
  3. #define LL long long
  4. #define dob complex<double>
  5. #define Abs(a) ((a) < 0 ? (-(a)) : (a))
  6. #define Max(a, b) ((a) > (b) ? (a) : (b))
  7. #define Min(a, b) ((a) < (b) ? (a) : (b))
  8. #define Swap(a, b) ((a) ^= (b), (b) ^= (a), (a) ^= (b))
  9. #define writeln(x) (write(x), putchar('\n'))
  10. #define lowbit(x) ((x)&(-(x)))
  11. using namespace std;
  12. const int N = 50000, INF = 5e8, yzh = 10007;
  13. void read(int &x) {
  14. char ch; bool flag = 0;
  15. for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar());
  16. for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar());
  17. x *= 1-2*flag;
  18. }
  19. void print(int x) {if (x > 9) print(x/10); putchar(x%10+48); }
  20. void write(int x) {if (x < 0) putchar('-'); print(Abs(x)); }
  21. int n, m, a[N+5], len, lef[N+5], f[N+5], s[N+5];
  22. bool judge(int x) {
  23. int cnt = 1, ret = 0;
  24. for (int i = 1; i <= n; i++) {
  25. if (a[i] > x) return false;
  26. if (ret+a[i] > x) ret = a[i], ++cnt; else ret += a[i];
  27. }
  28. return cnt <= m;
  29. }
  30. void solve1() {
  31. int l = 1, r = INF, ans;
  32. while (l <= r) {
  33. int mid = (l+r)>>1; if (judge(mid)) ans = mid, r = mid-1; else l = mid+1;
  34. }
  35. write(len = ans), putchar(' ');
  36. }
  37. void solve2() {
  38. int now = 0, ans = 0;
  39. for (int i = 1; i <= n; i++) {
  40. a[i] += a[i-1];
  41. while (a[i]-a[now] > len) ++now;
  42. lef[i] = now;
  43. }
  44. for (int i = 0; i <= n; i++) s[i] = 1;
  45. for (int len = 1; len <= m; len++) {
  46. for (int i = 1; i <= n; i++) f[i] = (lef[i] == 0 ? s[i-1] : s[i-1]-s[lef[i]-1]);
  47. s[0] = 0; for (int i = 1; i <= n; i++) s[i] = (f[i]+s[i-1])%yzh;
  48. ans = (ans+f[n])%yzh;
  49. }
  50. write((ans+yzh)%yzh);
  51. }
  52. void work() {
  53. read(n), read(m); ++m; for (int i = 1; i <= n; i++) read(a[i]);
  54. solve1(); solve2();
  55. }
  56. int main() {
  57. work(); return 0;
  58. }

[HAOI 2008]木棍分割的更多相关文章

  1. BZOJ 1044 木棍分割 解题报告(二分+DP)

    来到机房刷了一道水(bian’tai)题.题目思想非常简单易懂(我的做法实际上参考了Evensgn 范学长,在此多谢范学长了) 题目摆上: 1044: [HAOI2008]木棍分割 Time Limi ...

  2. 【BZOJ】【1044】【HAOI2008】木棍分割

    二分/DP 真是一道好题! 第一问很简单的二分…… 第二问一开始我想成贪心了,其实应该是DP的= = 然后没有注意……又MLE又TLE的……这题要对DP进行时空两方面的优化!! 题解:(by JoeF ...

  3. BZOJ1044: [HAOI2008]木棍分割

    1044: [HAOI2008]木棍分割 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1580  Solved: 567[Submit][Statu ...

  4. 【czy系列赛】czy的后宫6 && bzoj1044 [HAOI2008]木棍分割

    题目描述 众所周知的是丧尸czy有很多妹子(虽然很多但是质量不容乐观QAQ),今天czy把n个妹子排成一行来检阅.但是czy的妹子的质量实在--所以czy看不下去了.检阅了第i个妹子会增加czy a[ ...

  5. BZOJ 1044: [HAOI2008]木棍分割(二分答案 + dp)

    第一问可以二分答案,然后贪心来判断. 第二问dp, dp[i][j] = sigma(dp[k][j - 1]) (1 <= k <i, sum[i] - sum[k] <= ans ...

  6. 木棍分割[HAOI2008]

    题目描述 有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个连接处, 砍完后n根木棍被分成了很多段,要求满足总长度最大的一段长度最小, 并且 ...

  7. bzoj1044[HAOI2008]木棍分割 单调队列优化dp

    1044: [HAOI2008]木棍分割 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4314  Solved: 1664[Submit][Stat ...

  8. 【BZOJ1044】[HAOI2008]木棍分割(动态规划,贪心)

    [BZOJ1044][HAOI2008]木棍分割(动态规划,贪心) 题面 BZOJ 洛谷 题解 第一问随便二分一下就好了,贪心\(check\)正确性显然. 第二问随便前缀和+单调队列优化一下\(dp ...

  9. 【BZOJ1044】[HAOI2008]木棍分割

    [BZOJ1044][HAOI2008]木棍分割 题面 bzoj 洛谷 题解 第一问显然可以二分出来的. 第二问: 设\(dp[i][j]\)表示前\(i\)个,切了\(j\)组的方案数 发现每次转移 ...

随机推荐

  1. php数组排序和查找的算法

    1.php算法 // 算法 // 1.冒泡排序 => 思路:​每次循环排列出一个最大的数 // echo '<pre>'; $arr = [ 1,43,54,62,21,66,32, ...

  2. beta冲刺6

    前言:此篇是补昨天凌晨的.后面有更新但是太晚了就没有即使更新.所以现在过来更新一下. 昨天的未完成: 用户测试+测试报告 目前剩下的功能点:输入内容检测 我的社团输出显示格式调整. 今天的完成: 我的 ...

  3. Git学习使用

    1.注册码云并建立远程仓库 2.安装git 3.使用eclipse egit 推送以及克隆 建立本地仓库,成功后如图 推送项目至本地仓库与远程仓库 使用右键菜单team-share 选项,与仓库关联后 ...

  4. Flask 扩展 用户会话

    pip install flask-login 接下来创建扩展对象实例: from flask import Flask from flask_login import LoginManager ap ...

  5. Tornado介绍及自定义组件

    Tornado 的性能是相当优异的,因为它试图解决一个被称之为"C10k"问题,就是处理大于或等于一万的并发.一万呀,这可是不小的量 条件:处理器为 AMD Opteron, 主频 ...

  6. android批量打包

    http://blog.csdn.net/johnny901114/article/details/48714849

  7. PostgreSQL 客户端乱码问题

    关于客户端和服务器端的乱码问题, POSTGRESQL字符集问题总结 总结的很详细, 特别棒. 这里让我头痛了很久的问题在于 终端 上字符编码的问题, 由于我的mbp上的 iterm2 的默认编码为 ...

  8. jsp文件调用本地文件的方法(Tomcat server.xml 设置虚拟目录)

    JSP文件: <video id="my-video" class="video-js" controls preload="auto" ...

  9. Node入门教程(4)第三章:第一个 Nodejs 程序

    第一个 Nodejs 程序 本教程仅适合您已经有一定的JS编程的基础或者是后端语言开发的基础.如果您是零基础,建议您先学一下老马的前端免费视频教程 第一步:创建项目文件夹 首先创建 demos 文件夹 ...

  10. vue 在methods中调用mounted中的方法?

    首先可以在data中先声明一个变量 比如 isShow=' ' mounted 中 ---> methods 中 --->  this.sureDelBox(item) 直接this调用 ...