[BZOJ1044][HAOI2008]木棍分割 二分 + 单调队列优化dp + 滚动数组优化dp
Description
有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个连
接处, 砍完后n根木棍被分成了很多段,要求满足总长度最大的一段长度最小, 并且输出有多少种砍的方法使得总长
度最大的一段长度最小. 并将结果mod 10007。。。
Input
输入文件第一行有2个数n,m.接下来n行每行一个正整数Li,表示第i根木棍的长度.n<=50000,0<=m<=min(n-1,10
00),1<=Li<=1000.
Output
输出有2个数, 第一个数是总长度最大的一段的长度最小值, 第二个数是有多少种砍的方法使得满足条件.
Sample Input
1
1
10
Sample Output
HINT
两种砍的方法: (1)(1)(10)和(1 1)(10)
Solution
做法:二分+单调队列优化+滚动数组优化
第一问直接二分答案然后暴力$check$一下就行了,套路
第二问的话呢,用$dp$来求出答案
可以设$f[i][j]$表示前$i$个木棍切成$j$段时最大长度不大于第一问的$ans$的方案数
那么$$f[i][j]=\sum_{k}^{k<=i}f[k][j-1](sum[i]-sum[k-1]>=ans1)$$
那个$sum$前缀和一下就可以了
然而$dp$空间爆炸,但是可以发现切成$j$个时只会从$j-1$转移过来,所以滚动掉$j$这一维
然后就会发现时间爆炸,不过可以发现对于每个$i$,转移的$k$是固定的,所以拿个单调队列扫一扫就行了
#include <bits/stdc++.h> using namespace std ; #define N 100010
#define inf 0x3f3f3f3f
#define mod 10007 int n , m ;
int a[ N ] , f[ ][ N ] , q[ N ] , sum[ N ] ; bool check( int x ) {
int sum = , cnt = ;
for( int i = ; i <= n ; i ++ ) {
if( sum + a[ i ] > x ) sum = , cnt ++ ;
sum += a[ i ] ;
if( a[ i ] > x ) return ;
if( cnt > m ) return ;
}
return ;
} int main() {
scanf( "%d%d" , &n , &m ) ;
int l = inf , r , ans ;
for( int i = ; i <= n ; i ++ ) {
scanf( "%d" , &a[ i ] ) ;
l = min( l , a[ i ] ) ;
sum[ i ] = sum[ i - ] + a[ i ] ;
}
r = sum[ n ] ;
while( l <= r ) {
int mid = ( l + r ) >> ;
if( check( mid ) ) ans = mid , r = mid - ;
else l = mid + ;
}
printf( "%d " , ans ) ;
f[ ][ ] = ;
int ans2 = ;
for( int i = ; i <= m ; i ++ ) {
int pre = i& , cur = pre^ , tot = f[ cur ][ ] ;
l = , r = ;
q[ ] = ;
for( int j = ; j <= n ; j ++ ) {
while( l <= r && sum[ j ] - sum[ q[ l ] ] > ans )
tot = ( tot - f[ cur ][ q[ l ++ ] ] + mod ) % mod ;
f[ pre ][ j ] = tot ;
q[ ++ r ] = j ;
tot = ( tot + f[ cur ][ j ] + mod ) % mod ;
}
for( int j = n - ; j ; j -- ) {
if( sum[ n ] - sum[ j ] > ans ) break ;
ans2 = ( ans2 + f[ pre ][ j ] + mod ) % mod ;
}
memset( f[ cur ] , , sizeof( f[ cur ] ) ) ;
}
printf( "%d\n" , ans2 ) ;
return ;
}
[BZOJ1044][HAOI2008]木棍分割 二分 + 单调队列优化dp + 滚动数组优化dp的更多相关文章
- [BZOJ1044][HAOI2008]木棍分割 二分+贪心+dp+前缀和优化
1044: [HAOI2008]木棍分割 Time Limit: 10 Sec Memory Limit: 162 MB Submit: 4112 Solved: 1577 [Submit][St ...
- [bzoj1044][HAOI2008][木棍分割] (二分+贪心+dp+队列优化)
Description 有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个连接处, 砍完后n根木棍被分成了很多段,要求满足总长度最大的一段长 ...
- bzoj1044: [HAOI2008]木棍分割 二分+dp
有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个连接处, 砍完后n根木棍被分成了很多段,要求满足总长度最大的一段长度最小, 并且输出有多少 ...
- bzoj1044[HAOI2008]木棍分割 单调队列优化dp
1044: [HAOI2008]木棍分割 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 4314 Solved: 1664[Submit][Stat ...
- BZOJ1044 [HAOI2008]木棍分割 【二分+Dp】
1044: [HAOI2008]木棍分割 Time Limit: 10 Sec Memory Limit: 162 MB Submit: 4281 Solved: 1644 [Submit][St ...
- BZOJ1044: [HAOI2008]木棍分割
1044: [HAOI2008]木棍分割 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1580 Solved: 567[Submit][Statu ...
- BZOJ 1044: [HAOI2008]木棍分割(二分答案 + dp)
第一问可以二分答案,然后贪心来判断. 第二问dp, dp[i][j] = sigma(dp[k][j - 1]) (1 <= k <i, sum[i] - sum[k] <= ans ...
- 【动态规划】bzoj1044: [HAOI2008]木棍分割
需要滚动优化或者short int卡空间 Description 有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个连接处, 砍完后n根木棍 ...
- HDU_1024.MaxSumPlusPlus(基础DP + 滚动数组优化讲解)
这道题打破了我常规的做题思路,因为这是我刚开始训练DP,感觉这道题目好晕眼呀,emm其实就是感觉自己是真的菜...... 为什么说打破了我的做题思路呢,因为我平时看题解都是在已经AC或者完全不懂的情况 ...
随机推荐
- Java实现批量插入
//方法执行的开始时间 long startTime = System.currentTimeMillis(); Connection conn = null; try{ //获取连接 conn = ...
- mac chrome 驱动配置
将解压后的chromedriver移动到/usr/local/bin目录下
- 07_Linux 终端命令格式
Linux 终端命令格式 目标 了解终端命令格式 知道如何查阅终端命令帮助信息 01. 终端命令格式 command [-options] [parameter] 说明: command:命令名,相应 ...
- PHP移动互联网开发笔记(6)——MySQL数据库基础回想
近期看了一些架构方面的资料.可是发现基础知识都不怎么坚固,接下来的一段时间.我会定期总结基础知识. 一.数据类型 1.整型 数据类型 存储空间 说明 取值范围 TINYINT 1字节 很小的整 ...
- 既生list何生tuple
python中list是可以修改的;若要创建一系列不可修改的元素时,就需要tuple. 用 tuple 的好处: 1.tuple 比 list 操作速度快.如果您定义了一个值的常量集,并且唯一要用它做 ...
- Biorhythms(中国剩余定理)
http://shuxueshi.jie.blog.163.com/blog/static/13611628820104179856631/ 这篇博客写的很棒! #include<stdio.h ...
- PAT 1072 Gas Station[图论][难]
1072 Gas Station (30)(30 分) A gas station has to be built at such a location that the minimum distan ...
- 为什么要用Markov chain Monte Carlo (MCMC)
马尔科夫链的蒙特卡洛采样的核心思想是构造一个Markov chain,使得从任意一个状态采样开始,按该Markov chain转移,经过一段时间的采样,逼近平稳分布stationary distrib ...
- 集成树模型使用自动搜索模块GridSearchCV,stacking
一. GridSearchCV参数介绍 导入模块: from sklearn.model_selection import GridSearchCV GridSearchCV 称为网格搜索交叉验证调参 ...
- Python 之 os.walk()
原文地址https://www.cnblogs.com/JetpropelledSnake/p/8982495.html http://www.runoob.com/python/o ...