1044: [HAOI2008]木棍分割

Time Limit: 10 Sec  Memory Limit: 162 MB

Submit: 4281  Solved: 1644

[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

3 2


1

1

10

Sample Output

10 2

HINT

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

显然我们可以二分算出第一问

算出第一问后,我们就可以dp求方案数了

设f[i][j]表示前i个木棒割j刀的方案数

则f[i][j] = ∑f[k][j - 1]  【k < i 且 sum[i] - sum[k] <= mx】

但这样做会爆

首先我们可以滚动数组,空间不爆了

其次我们会发现sum是递增的,也就是说k可以k + 1 ~ i - 1一定都可以,我们每次维护一次f的前缀和就可以加速了

【注意:取模过程中涉及减法,最后答案输出时要取回正数】

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long int
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define Redge(u) for (int k = head[u]; k != -1; k = edge[k].next)
using namespace std;
const int maxn = 50005,maxm = 1005,INF = 1000000000,P = 10007;
inline int RD(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57) {if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57) {out = (out << 1) + (out << 3) + c - '0'; c = getchar();}
return out * flag;
}
int n,m,f[2][maxn],A[maxn],sum[maxn],S[maxn],mx = 0,Sum = 0,ans = 0;
bool check(int M){
if (mx > M) return false;
int cnt = 0,tot = 0;
for (int i = 1; i <= n; i++){
if (tot + A[i] > M) cnt++,tot = 0;
tot += A[i];
if (cnt > m) return false;
}
return true;
}
int main(){
n = RD(); m = RD();
REP(i,n) A[i] = RD(),sum[i] = sum[i - 1] + A[i],mx = max(mx,A[i]);
int l = 1,r = sum[n],mid;
while (l < r){
mid = l + r >> 1;
if (check(mid)) r = mid;
else l = mid + 1;
}
cout<<(mx = l)<<' ';
f[0][0] = 1;
for (int k = 0,p = 0; k <= m; k++){
S[0] = f[p][0];
REP(i,n) S[i] = (S[i - 1] + f[p][i]) % P;
p ^= 1; int pos = 0;
f[p][0] = 0;
for (int i = 1; i <= n; i++){
/*
for (int j = i - 1; j > 0; j--)
if (sum[i] - sum[j] <= mx)
f[p][i] = (f[p][i] + f[p ^ 1][j]) % P;
else break;*/
while (sum[i] - sum[pos] > mx) pos++;
f[p][i] = (S[i - 1] - (pos ? S[pos - 1] : 0)) % P;
}
ans = (ans + f[p][n]) % P;
}
cout<<(ans + P) % P<<endl;
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. 【bzoj1044】[HAOI2008]木棍分割 二分+dp

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

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

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

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

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

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

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

  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. maven-生命周期与插件

    Maven的生命周期是抽象的,具体的操作由插件实现,类似于java的模板设计模式. 1.生命周期 认识生命周期 maven有clean.default.site三种生命周期,每种生命周期都包含一些阶段 ...

  2. 仿制用友U8界面

    unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System ...

  3. Hadoop(13)-MapReduce框架原理--Job提交源码和切片源码解析

    1.MapReduce的数据流 1) Input -> Mapper阶段 这一阶段的主要分工就是将文件切片和把文件转成K,V对 输入源是一个文件,经过InputFormat之后,到了Mapper ...

  4. Leecode刷题之旅-C语言/python-9.回文数

    /* * @lc app=leetcode.cn id=9 lang=c * * [9] 回文数 * * https://leetcode-cn.com/problems/palindrome-num ...

  5. Awakening Your Senses【唤醒你的感觉官能】

    Awakening Your Senses Give youself a test. Which way is the wind blowing? How many kinds of wildflow ...

  6. JS正则表达式笔记

    正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串.将匹配的子串替换或者从某个串中取出符合某个条件的子串等. 正则 描述 ...

  7. 12 TCP服务器 进程 线程 非阻塞

    1.单进程服务器 from socket import * serSocket = socket(AF_INET, SOCK_STREAM) # 重复使用绑定的信息 serSocket.setsock ...

  8. EF使用报错说缺少引用

            在程序中已经引用了EF,也引用了System.Data,但是一起报这个错误:        在类前面也已经写了 using System.Data.Entity,百思不得其解,最后才发 ...

  9. springmvc常用jar包

    <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans ...

  10. jmeter无法启动的解决办法

    jmeter下载地址: 链接: https://pan.baidu.com/s/15YhiPH-kNVxISEZ4Mxf_WA     提取码: 25sv jdk 8.0 下载地址: 链接: http ...