2021.12.06 P2511 [HAOI2008]木棍分割(动态规划)
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\) 组,那么
fin=\sum_{i=1}^{m+1}f[i][n]
\]
一看就懂,时间复杂度为傲人的 \(O(n^3)\) ,你可以试试,反正我挂了 。
忽然发现
f[i][j]=g[i-1][j]-g[i-1][pos[j]-1]
\]
时间复杂度依旧傲人,不过好了很多,成为 \(O(n^2)\) 。不过你确定不想想空间吗?2个 \(1e7\) 的数组也不小啊。
继续优化:实际上 f 与 g 只和上一轮有关,滚动成一维数组就成~
代码如下:
#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]木棍分割(动态规划)的更多相关文章
- 2021.12.06 P2508 [HAOI2008]圆上的整点(数论+ π )
2021.12.06 P2508 [HAOI2008]圆上的整点(数论+ \(\pi\) ) https://www.luogu.com.cn/problem/P2508 题意: 求一个给定的圆 \( ...
- 2021.12.06 P1450 [HAOI2008]硬币购物(组合数学+抽屉原理+DP)
2021.12.06 P1450 [HAOI2008]硬币购物(组合数学+抽屉原理+DP) https://www.luogu.com.cn/problem/P1450 题意: 共有 44 种硬币.面 ...
- P2511 [HAOI2008]木棍分割
目录 Description Solution Code Description 有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个连接处, ...
- [洛谷P2511][HAOI2008]木棍分割
题目大意:有$n(n\leqslant5\times10^4)$根木棍,连续放在一起,把它们分成$m(\leqslant10^3)$段,要求使得最长的段最短,问最短的长度以及方案数 题解:要使得最长的 ...
- Luogu P2511 [HAOI2008]木棍分割 二分+DP
思路:二分+DP 提交:3次 错因:二分写萎了,$cnt$记录段数但没有初始化成$1$,$m$切的次数没有$+1$ 思路: 先二分答案,不提: 然后有个很$naive$的$DP$: 设$f[i][j] ...
- 题解—P2511 [HAOI2008]木棍分割
这道题第一眼直接一个二分板子把第一问解决掉,然后主要是统计方案. 其实这个方程还不算难推,只要推出来朴素 \(dp\) ,之后的一步一步也很顺理成章,所以这种题主要看能不能静下心来慢慢做. solut ...
- luogu P2511 [HAOI2008]木棍分割
传送门 第一问是一道经典的二分,二分答案\(ans\),然后从前往后扫,判断要分成几段救星了 第二问设\(f_{i,j}\)表示前\(i\)个数分成\(j\)段,每段之和不超过第一问答案的方案,转移就 ...
- 2021.12.06 P2501 [HAOI2006]数字序列(动态规划+LIS)
2021.12.06 P2501 [HAOI2006]数字序列(动态规划+LIS) https://www.luogu.com.cn/problem/P2501 题意: 现在我们有一个长度为 n 的整 ...
- 【BZOJ1044】[HAOI2008]木棍分割(动态规划,贪心)
[BZOJ1044][HAOI2008]木棍分割(动态规划,贪心) 题面 BZOJ 洛谷 题解 第一问随便二分一下就好了,贪心\(check\)正确性显然. 第二问随便前缀和+单调队列优化一下\(dp ...
随机推荐
- sql语言:如何查询字符串某个字符的个数?
sql语言:如何查询字符串某个字符的个数? 这语句太精彩了! select len('05011045')-len(replace('05011045','0',''))
- 面向对象编程(C++篇4)——RAII
目录 1. 概述 2. 详论 2.1. 堆.栈.静态区 2.2. 手动管理资源的弊端 2.3. 间接使用 2.4. 自下而上的抽象 3. 总结 4. 参考 1. 概述 在前面两篇文章<面向对象编 ...
- 如果有大量的 key 需要设置同一时间过期,一般需要注意什么?
如果大量的 key 过期时间设置的过于集中,到过期的那个时间点,redis 可能 会出现短暂的卡顿现象.一般需要在时间上加一个随机值,使得过期时间分散一 些.
- ACL 权限控制机制 ?
UGO(User/Group/Others) 目前在 Linux/Unix 文件系统中使用,也是使用最广泛的权限控制方式.是一种粗 粒度的文件系统权限控制模式. ACL(Access Control ...
- Zookeeper 保证了如下分布式一致性特性?
1.顺序一致性 2.原子性 3.单一视图 4.可靠性 5.实时性(最终一致性) 客户端的读请求可以被集群中的任意一台机器处理,如果读请求在节点上注册了 监听器,这个监听器也是由所连接的 zookeep ...
- 利用Matlab快速绘制栅格地图
代码演示 % 基于栅格地图的机器人路径规划算法 % 第1节:利用Matlab快速绘制栅格地图 clc clear close all %% 构建颜色MAP图 cmap = [1 1 1; ... % ...
- d面试题汇总
HTML Doctype作用,HTML5 为什么只需要写<!DOCTYPE HTML>? html5有哪些新特性?移除了哪些元素? 简述一下你对HTML语义化的理解? 行内元素有哪些,块级 ...
- 基于HTML5的网络拓扑图(1)
什么是网络拓扑 网络拓扑,指构成网络的成员间特定的排列方式.分为物理的,即真实的.或者逻辑的,即虚拟的两种.如果两个网络的连接结构相同,我们就説它们的网络拓扑相同,尽管它们各自内部的物理接线.节点间距 ...
- JS练习实例--编写经典小游戏俄罗斯方块
最近在学习JavaScript,想编一些实例练练手,之前编了个贪吃蛇,但是实现时没有注意使用面向对象的思想,实现起来也比较简单所以就不总结了,今天就总结下俄罗斯方块小游戏的思路和实现吧(需要下载代码也 ...
- css3 nth-child选择器
css3 nth-child选择器 css3的nth-child选择器,乍看起来很简单,其实不是那么容易. 简单用法 p:nth-child(n) // 选择属于其父元素的第n个子元素的每个 < ...