BZOJ 1044 木棍分割(二分答案 + DP优化)
题目链接 木棍分割
1044: [HAOI2008]木棍分割
Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 3830 Solved: 1453
[Submit][Status][Discuss]
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)
Source
第一个问题显然用二分解决,答案为len
第二个问题考虑DP,f[i][j]表示前i根木棒切j刀之后长度最大的一段不超过len的方案数。
则状态转移方程为 f[i][j] = sum(f[k][j - 1])
其中k必须满足 s[i] - s[k] <= len
这样做的话空间复杂度和时间复杂度都超过了限制,所以我们需要优化
空间复杂度方面,因为f[i][j]是从f[i][j - 1]推导而来,所以f的第二维可以用滚动数组来代替。
时间复杂度方面,我们发现大量的时间浪费在判断s[i] - s[k] <= len上,
因为随着j的递增每次符合s[i] - s[k] <= len的k的最大值是不下降的,
那么维护一个类似two-pointer的东西就可以了。
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i)
#define dec(i, a, b) for (int i(a); i >= (b); --i) typedef long long LL; const int N = 50010;
const int mod = 10007; int n, m;
int a[N], s[N], f[N][2];
int l, r, ans;
int len, cnt;
int k, now; inline bool check(int x){
int now = a[1], ret = 0;
rep(i, 2, n){
if (now + a[i] <= x){
now += a[i];
} else{
now = a[i];
++ret;
}
} return ret <= m;
} int main(){ scanf("%d%d", &n, &m);
rep(i, 1, n){
scanf("%d", a + i);
l = max(l, a[i]);
r += a[i];
s[i] = s[i - 1] + a[i];
} l = 0, r = 1e8; while (l + 1 < r){
int mid = (l + r) >> 1;
if (check(mid)) r = mid;
else l = mid + 1;
} if (check(l)) len = l; else len = r; rep(i, 0, m){
cnt = 0;
k = 1;
rep(j, 1, n){
if (i == 0){
if (s[j] <= len) f[j][now] = 1;
else f[j][now] = 0;
} else{
while (k < j && s[j] - s[k] > len){
cnt -= f[k][now ^ 1];
cnt = (cnt + mod) % mod;
++k;
}
f[j][now] = cnt;
} cnt = (cnt + f[j][now ^ 1]) % mod;
} (ans += f[n][now]) %= mod;
now ^= 1;
} printf("%d %d\n", len, ans);
return 0;
}
BZOJ 1044 木棍分割(二分答案 + DP优化)的更多相关文章
- BZOJ 1044: [HAOI2008]木棍分割(二分答案 + dp)
第一问可以二分答案,然后贪心来判断. 第二问dp, dp[i][j] = sigma(dp[k][j - 1]) (1 <= k <i, sum[i] - sum[k] <= ans ...
- BZOJ 1044 木棍分割 解题报告(二分+DP)
来到机房刷了一道水(bian’tai)题.题目思想非常简单易懂(我的做法实际上参考了Evensgn 范学长,在此多谢范学长了) 题目摆上: 1044: [HAOI2008]木棍分割 Time Limi ...
- [BZOJ1044][HAOI2008]木棍分割 二分 + 单调队列优化dp + 滚动数组优化dp
Description 有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个连接处, 砍完后n根木棍被分成了很多段,要求满足总长度最大的一段长 ...
- [BZOJ1044][HAOI2008]木棍分割 二分+贪心+dp+前缀和优化
1044: [HAOI2008]木棍分割 Time Limit: 10 Sec Memory Limit: 162 MB Submit: 4112 Solved: 1577 [Submit][St ...
- 【BZOJ】1044: [HAOI2008]木棍分割 二分+区间DP
链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1044 Description 有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, ...
- [bzoj1044][HAOI2008][木棍分割] (二分+贪心+dp+队列优化)
Description 有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个连接处, 砍完后n根木棍被分成了很多段,要求满足总长度最大的一段长 ...
- BZOJ 1044 木棍分割
二分+dp. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm ...
- BZOJ_1044_[HAOI2008]木棍分割_二分答案+DP+单调队列
BZOJ_1044_[HAOI2008]木棍分割_二分答案+DP Description 有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个 ...
- 洛谷 P1800 software_NOI导刊2010提高(06)(二分答案+DP检验)
P1800 software_NOI导刊2010提高(06) 标签 二分答案 难度 普及/提高- 题目描述 一个软件开发公司同时要开发两个软件,并且要同时交付给用户,现在公司为了尽快完成这一任务,将每 ...
随机推荐
- 示例vue 的keep-alive缓存功能的实现
本篇文章主要介绍了vue 的keep-alive缓存功能的实现,写的十分的全面细致,具有一定的参考价值,对此有需要的朋友可以参考学习下.如有不足之处,欢迎批评指正. Vue 实现组件信息的缓存 当我们 ...
- vue 使用lib-flexable,px2rem 进行移动端适配 但是引入的第三方UI组件 vux 的样式缩小,解决方案
最近在写移动端项目,就想用lib-flexable,px2rem来进行适配,把px转换成rem但是也用到了第三方UI组件库vux,把这个引入发现一个问题就是vux的组件都缩小了,在网上找不到答案,最后 ...
- Python入门学习笔记2:刷题
1) LeetCode 强的面试题和算法题,要求也比较高,很多国内外的码农在上面刷题.难度从easy到hard都有,而且覆盖面极广,需要你的综合实力去答题. 最简单的题比如字符串的处理有的时候也要用到 ...
- poj 1017 装箱子问题 贪心算法
题意:有1*1到6*6的的东西,需要用6*6的箱子将它们装起来.问:至少需要多少个6*6箱子 思路: 一个瓶子怎么装东西最多?先装石头,在装沙子,然后装水. 同样放在本题就是先装6*6然后5*5... ...
- BZOJ 2465: [中山市选2009]小球
难度在于读题 #include<cstdio> #include<algorithm> using namespace std; int a[1000005]; struct ...
- 2015四川省赛 D Vertex Cover 搜索
题意: 给出一个\(n\)个点\(m\)条边的无向图,现在要给若干个点染色,使得每条边都至少邻接一个被染色的顶点.问至少要给多少各点染色才能满足条件. 分析: 注意到题目中有一个很特殊的条件: 对于图 ...
- matlab图形handle
- cinema 4d 包括宝典 --- 改线 循环边 建模布线原则
cinema 4d 一.视图控制与物体控制 1.摇移 alt+鼠标左键 转圈看物体 改变角度 2.平移 alt +鼠标中键 不改变角度 移动 3.推拉 alt+鼠标右键 ...
- Educational Codeforces Round 37 (Rated for Div. 2)
我的代码应该不会被hack,立个flag A. Water The Garden time limit per test 1 second memory limit per test 256 mega ...
- Educational Codeforces Round 20 B. Distances to Zero
B. Distances to Zero time limit per test 2 seconds memory limit per test 256 megabytes input standar ...