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

https://www.luogu.com.cn/problem/P2511

题意:

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

分析:

对于第一问,首先二分答案找出ans。

对于第二问,设 sum[i] 表示前 \(i\) 个木棍的长度之和,对于每个木棍 \(i\) ,可以找出在它最前面的木棍 \(j\) ,满足 \(sum_i-sum_j<=ans\) ,把结果存在数组 pos 中。对于前 \(j\) 根木棍分成 \(i\) 组,那么

\[f[i][j]=\sum_{k=pos_j}^{j-1}f[i-1][k]\\
fin=\sum_{i=1}^{m+1}f[i][n]
\]

一看就懂,时间复杂度为傲人的 \(O(n^3)\) ,你可以试试,反正我挂了 。

忽然发现

\[设g[i][j]=\sum_{k=1}^{j}f[i][k]\\
f[i][j]=g[i-1][j]-g[i-1][pos[j]-1]
\]

时间复杂度依旧傲人,不过好了很多,成为 \(O(n^2)\) 。不过你确定不想想空间吗?2个 \(1e7\) 的数组也不小啊。

继续优化:实际上 fg 只和上一轮有关,滚动成一维数组就成~

代码如下:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#define IOS ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std; const int N=5e4+10;
const int mod=1e4+7;
int n,m,sum[N],pos[N],a[N],f[N],g[N]; inline int check(int maxn){
int tot=0,len=0;
for(int i=1;i<=n;i++){
if(len+a[i]>maxn)++tot,len=a[i];
else len+=a[i];
if(tot>m)return 0;
}
return tot<=m;
} int main(){
IOS;
cin>>n>>m;
int L=0,R=0,ans;
for(int i=1;i<=n;i++)cin>>a[i],sum[i]=sum[i-1]+a[i],L=max(L,a[i]);
R=sum[n];
while(L<R){
int mid=(L+R)>>1;
if(check(mid))ans=mid,R=mid;
else L=mid+1;
}
cout<<ans<<" ";
int lasti=0;
for(int i=1;i<=n;i++)
for(;lasti<i;lasti++)if(sum[i]-sum[lasti]<=ans){
pos[i]=lasti;
break;
}
int fin=sum[n]<=ans;
for(int i=1;i<=n;i++){
if(sum[i]<=ans)f[i]=1;
g[i]=(g[i-1]+f[i])%mod;
}
for(int i=2;i<=m+1;i++){
for(int j=1;j<=n;j++){
f[j]=g[j-1];
if(pos[j]>=1)f[j]=((f[j]-g[pos[j]-1])%mod+mod)%mod;
}
for(int j=1;j<=n;j++)g[j]=(g[j-1]+f[j])%mod;
fin=(fin+f[n])%mod;
}
cout<<fin;
return 0;
}

2021.12.06 P2511 [HAOI2008]木棍分割(动态规划)的更多相关文章

  1. 2021.12.06 P2508 [HAOI2008]圆上的整点(数论+ π )

    2021.12.06 P2508 [HAOI2008]圆上的整点(数论+ \(\pi\) ) https://www.luogu.com.cn/problem/P2508 题意: 求一个给定的圆 \( ...

  2. 2021.12.06 P1450 [HAOI2008]硬币购物(组合数学+抽屉原理+DP)

    2021.12.06 P1450 [HAOI2008]硬币购物(组合数学+抽屉原理+DP) https://www.luogu.com.cn/problem/P1450 题意: 共有 44 种硬币.面 ...

  3. P2511 [HAOI2008]木棍分割

    目录 Description Solution Code Description 有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个连接处, ...

  4. [洛谷P2511][HAOI2008]木棍分割

    题目大意:有$n(n\leqslant5\times10^4)$根木棍,连续放在一起,把它们分成$m(\leqslant10^3)$段,要求使得最长的段最短,问最短的长度以及方案数 题解:要使得最长的 ...

  5. Luogu P2511 [HAOI2008]木棍分割 二分+DP

    思路:二分+DP 提交:3次 错因:二分写萎了,$cnt$记录段数但没有初始化成$1$,$m$切的次数没有$+1$ 思路: 先二分答案,不提: 然后有个很$naive$的$DP$: 设$f[i][j] ...

  6. 题解—P2511 [HAOI2008]木棍分割

    这道题第一眼直接一个二分板子把第一问解决掉,然后主要是统计方案. 其实这个方程还不算难推,只要推出来朴素 \(dp\) ,之后的一步一步也很顺理成章,所以这种题主要看能不能静下心来慢慢做. solut ...

  7. luogu P2511 [HAOI2008]木棍分割

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

  8. 2021.12.06 P2501 [HAOI2006]数字序列(动态规划+LIS)

    2021.12.06 P2501 [HAOI2006]数字序列(动态规划+LIS) https://www.luogu.com.cn/problem/P2501 题意: 现在我们有一个长度为 n 的整 ...

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

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

随机推荐

  1. Zabbix 4.4管理界面中文乱码解决方法

    1.zabbix 4.4 安装配置过程可参考官方文档: 文档链接地址:https://www.zabbix.com/download?zabbix=4.4&os_distribution=ce ...

  2. IC设计学习路线

    一 前言 一直以来都是这也想学那也想学,搞个两三个月又放弃了,开始搞新的,从来没有任何东西超过一年,更不要说坚持三年.现在经历的事情多了,学过各种编程语言明白了要想学会一个专业技能,至少是三年.得到软 ...

  3. 时序数据库之InfluxDB的基本操作

    1.进入Influxdb的客户端 [root@activity_sentinel ~]# influx 2.数据库的操作 显示所有的数据库名 > show databases name: dat ...

  4. 什么是 bean 装配?

    装配,或 bean 装配是指在 Spring 容器中把 bean 组装到一起,前提是容器需要 知道 bean 的依赖关系,如何通过依赖注入来把它们装配到一起.

  5. 使用 Spring 有哪些方式?

    使用 Spring 有以下方式: 作为一个成熟的 Spring Web 应用程序. 作为第三方 Web 框架,使用 Spring Frameworks 中间层. 用于远程使用. 作为企业级 Java ...

  6. leetcode_9回文数

    给你一个整数 x ,如果 x 是一个回文整数,返回 true :否则,返回 false . 回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数. 例如,121 是回文,而 123 不是. 来 ...

  7. 4.3 ROS工作空间覆盖

    4.3 ROS工作空间覆盖 所谓工作空间覆盖,是指不同工作空间中,存在重名的功能包的情形. ROS 开发中,会自定义工作空间且自定义工作空间可以同时存在多个,可能会出现一种情况: 虽然特定工作空间内的 ...

  8. c、c++中-int型以float或者float型以int输出问题

    1.将浮点型以整形的类型输出问题 用VC6.0,会把以整形输出形式的浮点数输出为0: 1 #include"stdio.h" 2 int main() 3 { 4 float x= ...

  9. 使用jenkins实现前端自动化打包部署(Linux版本)

    我们这边好多小组觉得每次测试人员叫我们开发打包部署到某某个测试环境人工操作比较麻烦,因为他们想做到只专注于开发,不管这些琐碎的事.于是有个组长问我前端能不能用Jenkins去执行这一个固定的流程,因为 ...

  10. Vue.js 开发实践:实现精巧的无限加载与分页功能

    本篇文章是一篇Vue.js的教程,目标在于用一种常见的业务场景--分页/无限加载,帮助读者更好的理解Vue.js中的一些设计思想.与许多Todo List类的入门教程相比,更全面的展示使用Vue.js ...