题目描述

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

输入

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

输出

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

样例输入

3 2
1
1
10

样例输出

10 2

提示

两种砍的方法: (1)(1)(10)和(1 1)(10)

题解 

    人生第一道二分答案成就感满满!二分答案,是指在最小值和最大值之间二分枚举答案,逐渐把答案缩小到一个值得出最优解。二分答案的题目设问常常是最大值最小、最小值最大,解的可能性应该是单调的(即某值不可行则答案只能比它大或只能比它小),需要能简单地验证答案正确与否,要注意的就是防止死循环(不过这道题好像没有这个问题)。对于木棍分割,如果这个值可行,最优解可能比它更小,以它为上界看一看有没有更小的解;如果这个值不可行,只能舍弃它和比它更小的解,以它+1为下界搜索答案。
int check(long long x)
{
temp=he=0;
for(int i=1;i<=n;i++)
{
if(he+li[i]<=x)
he+=li[i];
else
{
he=li[i];
temp++;
if(temp>m)
return 0;
}
}
if(temp>m) return 0;
return 1;
}
le=yd,jg=zd;(最小解是单段木块长度的最大值,最大解是所有木块长度之和)
while(le<jg)
{
mid=(le+jg)>>1;
if(check(mid)) jg=mid;
else le=mid+1;
}
dp部分优化空间复杂度用滚动数组,优化时间复杂度用类似单调队列的思路,和Watching firework is fun大同小异,最后结果为f[i][n]之和。f[i][j]表示j段木块切i次的方案,f[i][j]为所有满足sum[i]-sum[k]<=jg的f[k][j-1]之和(1<=k<i)。f[i]只与f[i-1]有关,第一维只有0和1;sum是单调的,只要维护一个f[k][j-1]之和每次从后部加上新值,从头部减去不满足条件的k对应的值即可。 UPD:关于这个二分卡死的问题后来慢慢弄清了是怎么回事。并不是+1或不+1就容易被卡死,而是你要保证每次l和r总有一个是变化的。比如说mid=l+r>>1,那mid可能和l相等,你就不能if(……)l=mid,如果必须这样就得mid=(l+r+1)>>1。OI中的很多东西开始不明白,用了很长时间忽然就搞懂了,只有看清了内部的原理才是真正的通透啊。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int sj=;
int li[sj],mod=,yd;
int la,no,head,n,m,mid,temp,tail;
long long s[sj],f[][sj],zd,jg,le,he,fas;
int dbj(int x,int y)
{
return x>y?x:y;
}
int xbj(int x,int y)
{
return x<y?x:y;
}
void init()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
{
scanf("%d",&li[i]);
s[i]=s[i-]+li[i];
zd+=li[i];
yd=dbj(li[i],yd);
}
}
void dp()
{
for(int i=;i<=n;i++)
{
if(s[i]<=jg)
f[][i]=;
if(s[i]>jg)
break;
}
fas=f[][n];
for(int j=;j<=m;j++)
{
head=;
tail=;
he=;
la=(j+)%;
no=j%;
for(int i=;i<=n;i++)
{
if(i<j) continue;
for(int k=tail+;k<i;k++)
he+=f[la][k];
tail=i-;
while(s[i]-s[head]>jg)
{
he-=f[la][head];
head++;
}
f[no][i]=he;
f[no][i]%=mod;
}
fas+=f[no][n];
fas%=mod;
}
}
int check(long long x)
{
temp=he=;
for(int i=;i<=n;i++)
{
if(he+li[i]<=x)
he+=li[i];
else
{
he=li[i];
temp++;
if(temp>m)
return ;
}
}
if(temp>m) return ;
return ;
}
int main()
{
init();
le=yd,jg=zd;
while(le<jg)
{
mid=(le+jg)>>;
if(check(mid)) jg=mid;
else le=mid+;
}
printf("%lld\n",jg);
dp();
printf("%lld",fas);
//while(1);
return ;
}

木棍分割[HAOI2008]的更多相关文章

  1. 【BZOJ】【1044】【HAOI2008】木棍分割

    二分/DP 真是一道好题! 第一问很简单的二分…… 第二问一开始我想成贪心了,其实应该是DP的= = 然后没有注意……又MLE又TLE的……这题要对DP进行时空两方面的优化!! 题解:(by JoeF ...

  2. BZOJ1044: [HAOI2008]木棍分割

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

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

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

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

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

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

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

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

    [BZOJ1044][HAOI2008]木棍分割 题面 bzoj 洛谷 题解 第一问显然可以二分出来的. 第二问: 设\(dp[i][j]\)表示前\(i\)个,切了\(j\)组的方案数 发现每次转移 ...

  7. 1044: [HAOI2008]木棍分割

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

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

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

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

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

随机推荐

  1. jquery让页面滚动条top,滚动条 顶部

    jquery让页面滚动条top,滚动条 顶部$(document).scrollTop(0);

  2. PHP中对汉字进行UNICODE编码和解码的实现

    <?php /** PHP中对汉字进行UNICODE编码和解码的实现 **/ class Helper_Tool{ //php中的unicode编码转中文 static function uni ...

  3. CSS3学习系列之背景相关样式(一)

    新增属性: background-clip:指定背景的显示范围 background-origin:指定绘制背景图像时的起点 background-size:指定背景中图像的尺寸 background ...

  4. 想从事IT行业的你,一定看看这篇文章

    很多想从事IT行业的小伙伴都会问: 我该如何学习技术? 我应该选择什么样的方向来深入学习并以此来就业? 如何证明自己的技术很牛? 什么是程序员的核心竞争力? 如何成为一名优秀的工程师? 对于这些疑问, ...

  5. Educational Codeforces Round 23.C

    C. Really Big Numbers time limit per test 1 second memory limit per test 256 megabytes input standar ...

  6. diy toy: image auto-handler

    备忘之:) config.xml <?xml version="1.0" encoding="utf-8"?> <config> < ...

  7. vue.js 生命周期

    boforeCreate   创建之前 created            创建之后 boforeMount    实例化之前 mounted          实例化之后 话不多说,直接上代码 & ...

  8. Unity-Shader-动态阴影(上) 投影的矩阵变换过程

    [旧博客转移 - 2017年1月20日 01:20 ] 前面的话 最近很长时间没写博文了,一是太忙 ( lan ) 了,二是这段时间又领悟了一些东西,脑子里很混乱,不知道从何写起.但感觉不能再拖延下去 ...

  9. select2 4.0.3 空记录时的处理

    使用select2插件,如果后台查找没有记录,不能返回null,要返回一个空数组,不然会报错:data is null 空数组形式为(firefox调试输出):{"items":[ ...

  10. synchronized优化

    重量级锁 synchronized关键字 前文解释了synchronized的实现和运用,了解monitor的作用,但是由于monitor监视器锁的操作是基于操作系统的底层Mutex Lock实现的, ...