思路:二分+DP

提交:3次

错因:二分写萎了,$cnt$记录段数但没有初始化成$1$,$m$切的次数没有$+1$

思路:

先二分答案,不提;

然后有个很$naive$的$DP$:

设$f[i][j]$表示分成$i$段,到第$j$个木棍的方案数,$l$表示二分后的答案,

所以有$f[i][j]=\sum_{j到k+1根木棍的总长度\leq l}$            $f[i-1][k]$

$ans=\sum_{i=1}^{m+1}f[i][n]$

但他太慢了$QwQ$

于是我们优化一下:

把$f[i-1][1]$到$f[i-1][k]$前缀和一下记做$s[i-1][k]$,这样可以$O(1)$查区间;

然后对于每个木棍$j$,预处理"$j$到$k+1$根木棍的总长度$\leq l$"中的$k$,记为$pos[j]$

所以现在有$f[i][j]=s[i-1][j]-s[i-1][pos[j]-1]$

然后惊喜地发现第一维可以滚掉?!

代码:

  1. #include<cstdio>
  2. #include<iostream>
  3. #include<algorithm>
  4. using namespace std;
  5. #define ull unsigned long long
  6. #define ll long long
  7. #define R register ll
  8. #define pause (for(R i=1;i<=10000000000;++i))
  9. #define In freopen("NOIPAK++.in","r",stdin)
  10. #define Out freopen("out.out","w",stdout)
  11. namespace Fread {
  12. static char B[<<],*S=B,*D=B;
  13. #ifndef JACK
  14. #define getchar() (S==D&&(D=(S=B)+fread(B,1,1<<15,stdin),S==D)?EOF:*S++)
  15. #endif
  16. inline int g() {
  17. R ret=,fix=; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-:fix;
  18. if(ch==EOF) return EOF; do ret=ret*+(ch^); while(isdigit(ch=getchar())); return ret*fix;
  19. } inline bool isempty(const char& ch) {return (ch<=||ch>=);}
  20. inline void gs(char* s) {
  21. register char ch; while(isempty(ch=getchar()));
  22. do *s++=ch; while(!isempty(ch=getchar()));
  23. }
  24. } using Fread::g; using Fread::gs;
  25.  
  26. namespace Luitaryi {
  27. const int N=,M=;
  28. int n,m,pos[N];
  29. ll ans,mx,a[N],sum[N],f[N],s[N];
  30. inline bool ck(int x) { R cnt=,sum=;
  31. for(R i=;i<=n;++i) {
  32. if(sum+a[i]>x) sum=,++cnt;
  33. sum+=a[i];
  34. if(cnt>m+) return false;
  35. } return cnt<=m+;
  36. }
  37. inline void main() {
  38. n=g(),m=g();
  39. for(R i=;i<=n;++i) a[i]=g(),mx=max(a[i],mx),sum[i]=sum[i-]+a[i];
  40. R l=mx,r=sum[n]+;
  41. while(l<r) {
  42. R md=l+r>>; if(ck(md)) r=md;
  43. else l=md+;
  44. } printf("%d ",l); R p=;
  45. for(R i=;i<=n;++i) {
  46. while(sum[i]-sum[p]>l&&p<i) ++p;
  47. pos[i]=p;
  48. }
  49. for(R i=;i<=n;++i) f[i]=sum[i]<=l,s[i]=(s[i-]+f[i]); ans=sum[n]<=l;
  50. for(R i=;i<=m+;++i) {
  51. for(R j=;j<=n;++j) {
  52. f[j]=s[j-];
  53. if(pos[j]->) f[j]=((f[j]-s[pos[j]-])%M+M)%M;
  54. }
  55. for(R j=;j<=n;++j) s[j]=(s[j-]+f[j])%M;
  56. ans=(ans+f[n])%M;
  57. } printf("%lld\n",ans);
  58. }
  59. }
  60. signed main() {
  61. Luitaryi::main();
  62. return ;
  63. }

2019.07.19

Luogu P2511 [HAOI2008]木棍分割 二分+DP的更多相关文章

  1. 【bzoj1044】[HAOI2008]木棍分割 二分+dp

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

  2. luogu P2511 [HAOI2008]木棍分割

    传送门 第一问是一道经典的二分,二分答案\(ans\),然后从前往后扫,判断要分成几段救星了 第二问设\(f_{i,j}\)表示前\(i\)个数分成\(j\)段,每段之和不超过第一问答案的方案,转移就 ...

  3. bzoj1044: [HAOI2008]木棍分割 二分+dp

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

  4. 2021.12.06 P2511 [HAOI2008]木棍分割(动态规划)

    2021.12.06 P2511 [HAOI2008]木棍分割(动态规划) https://www.luogu.com.cn/problem/P2511 题意: 有n根木棍, 第i根木棍的长度为 \( ...

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

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

  6. [BZOJ1044][HAOI2008]木棍分割 二分+贪心+dp+前缀和优化

    1044: [HAOI2008]木棍分割 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 4112  Solved: 1577 [Submit][St ...

  7. 【BZOJ】1044: [HAOI2008]木棍分割 二分+区间DP

    链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1044 Description 有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, ...

  8. [BZOJ1044][HAOI2008]木棍分割 二分 + 单调队列优化dp + 滚动数组优化dp

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

  9. [bzoj1044][HAOI2008][木棍分割] (二分+贪心+dp+队列优化)

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

随机推荐

  1. 什么是阿里云SCDN

    简介 SCDN(Secure Content Delivery Network),即拥有安全防护能力的CDN服务,提供稳定加速的同时,智能预判攻击行为,通过智能的调度系统将DDoS攻击请求切换至高防I ...

  2. nginx文件服务器搭建

    一.安装 (CentOS 7) yum install nginx -y 如果报错: [u3@L3 /]$ sudo yum install nginx -y Loaded plugins: fast ...

  3. linux 从远程服务器拷贝文件

    1.从服务器复制文件到本地: scp root@192.168.1.100:/data/test.txt /home/myfile/ 2.从服务器复制文件夹到本地: scp -r root@192.1 ...

  4. 如何找到程序的真正入口mainCRTStartup

    相信大家都知道以为程序的入口为main函数,但是程序的真正的入口不是main而是mainCRTStartup,那么我们如何找到他的地址呢? 先用第一种方法,就是直接代码显示 #include<s ...

  5. 学习GTK+ (1) ——编写helloworld

    环境 我使用的是新安装的manjaro 18.1 (kde版),安装新系统后后直接可以开始写代码,不需要安装各种调用的库等. 推荐一个网站,gnome开发者 https://developer.gno ...

  6. 这里除了安全,什么都不会发生!Docker镜像P2P加速之路

    1.1      问题: 在使用Docker运行容器化应用时,宿主机通常先要从Registry服务(如Docker Hub)下载相应的镜像(image).这种镜像机制在开发环境中使用还是很有效的,团队 ...

  7. 怎样理解在函数中声明var x = y = 1后调用函数时, x是局部变量, y是全局变量

    下面这段代码在执行的时候, 打印的结果是1, Error: undefined; function fn() { var x = y = 1; } fn(); console.log(y); // 1 ...

  8. Unable to bind to http://localhost:8080 on the IPv6 loopback interface: 'Cannot assign requested address'.

    .net core+nginx警告: warn: Microsoft.AspNetCore.Server.Kestrel[0] Unable to bind to http://localhost:5 ...

  9. PyInstaller使用教程

    简介 PyInstaller是一个第三方库,它能够在Windows.Linux. Mac OS X 等操作系统下将 Python 源文件打包,通过对源文件打包, Python 程序可以在没有安装 Py ...

  10. centeros7安装mysql

    转载自:https://www.linuxidc.com/Linux/2016-09/135288.htm 安装之前先安装基本环境:yum install -y perl perl-Module-Bu ...