题目描述

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

输入

输入文件第一行有2个数n,m.接下来n行每行一个正整数Li,表示第i根木棍的长度.n<=50000,0<=m<=min(n-1,1000),1<=Li<=1000.

输出

输出有2个数, 第一个数是总长度最大的一段的长度最小值, 第二个数是有多少种砍的方法使得满足条件.

样例输入

3 2
1
1
10

样例输出

10 2


题解

二分+dp

第一问即 noip2015跳石头 。。。一眼二分,然后看不满足条件时就切一刀,判断是否小于m。

第二问求方案数,很显然是个dp。

设$f[i][j]$表示前$i$个分了$j$段的方案数,那么状态转移方程应该为$f[i][j]=\sum\limits_{len(t+1,i)\le ans1}f[t][j-1]$,边界条件$f[0][0]=1$,其中$len(a,b)表示$[a,b]$所有木棍的长度总和。

可以发现$t$的取值范围是一段连续的单调的区间,因此可以用类似双指针的方法扫出$t$的取值左端点。然后$\sum$又可以使用前缀和维护,这样时间复杂度就降为了$O(nm)$。

然而这样还会炸空间。。。

因此使用滚动数组就好了,显然第二维是可以滚动的,因此先枚举第二维,滚动一下就好了。

#include <cstdio>
#include <algorithm>
#define N 50010
#define mod 10007
using namespace std;
int n , m , a[N] , sl[N] , f[2][N] , sum[2][N];
bool judge(int mid)
{
int i , now = 0 , cnt = 0;
for(i = 1 ; i <= n ; i ++ )
{
if(now + a[i] > mid) now = 0 , cnt ++ ;
now += a[i];
}
return cnt <= m;
}
int main()
{
int i , j , l = 0 , r = 0 , mid , ans = -1 , p = 0 , ret = 0 , d;
scanf("%d%d" , &n , &m);
for(i = 1 ; i <= n ; i ++ ) scanf("%d" , &a[i]) , l = max(l , a[i]) , r += a[i] , sl[i] = sl[i - 1] + a[i];
while(l <= r)
{
mid = (l + r) >> 1;
if(judge(mid)) ans = mid , r = mid - 1;
else l = mid + 1;
}
printf("%d " , ans);
for(i = 0 ; i <= n ; i ++ ) sum[0][i] = 1;
for(i = d = 1 ; i <= m + 1 ; i ++ , d ^= 1)
{
sum[d][0] = p = 0;
for(j = 1 ; j <= n ; j ++ )
{
while(sl[j] - sl[p] > ans) p ++ ;
f[d][j] = sum[d ^ 1][j - 1];
if(p) f[d][j] = (f[d][j] - sum[d ^ 1][p - 1] + mod) % mod;
sum[d][j] = (sum[d][j - 1] + f[d][j]) % mod;
}
ret = (ret + f[d][n]) % mod;
}
printf("%d\n" , ret);
return 0;
}

【bzoj1044】[HAOI2008]木棍分割 二分+dp的更多相关文章

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

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

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

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

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

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

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

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

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

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

  6. BZOJ1044 [HAOI2008]木棍分割 【二分+Dp】

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

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

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

  8. bzoj1044[HAOI2008]木棍分割 单调队列优化dp

    1044: [HAOI2008]木棍分割 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4314  Solved: 1664[Submit][Stat ...

  9. BZOJ1044: [HAOI2008]木棍分割

    1044: [HAOI2008]木棍分割 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1580  Solved: 567[Submit][Statu ...

随机推荐

  1. Oracle必备知识.

    一.基本数据类型 1.字符数据类型 char    varchar2    long 三者区别:  I.char固定长度字符串,存储字母数字值,列长度可以是 1 到 2000 个字节. II.varc ...

  2. 12.1.0.2自适应特性导致SQL性能下降

    背景介绍 在升级到12.1.0.2.0数据库版本后,在使用12c中引入的自适应特性默认配置的情况下,可能引起SQL性能的下降. 问题现象升级到12.1.0.2.0后,SQL语句性能可能出现下降. 影响 ...

  3. AMD、CMD、Common规范及对比

    https://blog.csdn.net/bluesky1215/article/details/71081780  1.名词解释 AMD:Asynchronous Modules Definiti ...

  4. 简单了解:Web前端攻击方式及防御措施

    一.XSS [Cross Site Script]跨站脚本攻击  恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用 ...

  5. C++ 编写的解码器小程序 map

    c++ prime 5 ex11_4 代码如下 // ex11_4_word_transform.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h&quo ...

  6. Ubuntu安装MySQL及使用Xshell连接MySQL出现的问题(2003-Can't connect to MySql server及1045错误)

    不管在什么地方,什么时候,学习是快速提升自己的能力的一种体现!!!!!!!!!!! 以下所有的命令都是在root用户下操作(如果还没有设置root密码)如下: 安装好Ubuntu系统之后,打开终端先设 ...

  7. JS - 简单的下载图片至本地

    <iframe id="saveImg" src="图片路径" style="display:none;"></ifram ...

  8. ubuntu built-in display 产生的一个原因

    在没有禁用开源的显卡驱动 nouveau 下,从 apt 安装了nvidia的驱动,导致了后面开机后,系统不能正确的识别到显示器,整个界面分辨率变的非常小,在设置菜单中的显示设置中也不能调节分辨率,并 ...

  9. 【牛客 错题集】Linux系统方面错题合集

    前言:牛客Linux322道全部刷完,有些题目较老,甚至考核5系统,现在7都出来了几年了 = = 还有些题目解析的很好部分也摘录了进来.很多涉及嵌入式开发的选择题同样的摘录的作为了解使用 ------ ...

  10. SVN中Commit出现乱码的解决方案【转载】

    http://blog.csdn.net/thinkingcao/article/details/52797737 这几天在电脑上装了一个SVN,把Eclipse里面的工程全部Delete掉了,然后在 ...