对于这道题目的两问,第一问直接二分答案求出最短长度。关键在于第二问应当如何求:建立dp方程,dp[i][j]代表到第i个分界线,切了j次(强制在第i处切一刀、这样就不会对后面的状态产生影响)。状态转移的方程即是当前分界线枚举上一条分界线在哪里,上一条分界线与当前线之间如果相差不超过之前二分出来的答案,就可以判定合法,方案数累加。因为注意到合法的分界线必然是一段连续区间,且单调右移不减,所以使用一个队列来维护队列内的元素总值。虽然让我感到非常玄学的是明明数据很小,我的数组一开小了就WA?不是很理解……

#include <bits/stdc++.h>
using namespace std;
#define maxn 5000000
#define maxm 300000
#define mod 10007
#define INF 99999999
int m, maxx, fans, ans, a[maxn], sum[maxn], dp[maxm][], n, pre = , now = ;
int q[maxn], tot, head, tail;
bool mark[maxn];
int read()
{
int x = , k = ;
char c;
c = getchar();
while(c < '' || c > '') { if(c == '-') k = -; c = getchar(); }
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x * k;
} bool check(int x)
{
int cnt = m;
int tem = ;
for(int i = ; i <= n; i ++)
{
if(tem + a[i] <= x) tem += a[i];
else
{
if(!cnt) return false;
tem = a[i], cnt --;
}
}
return true;
} void solve()
{
int l = maxx, r = sum[n];
while(l <= r)
{
int mid = (l + r) >> ;
if(check(mid)) ans = mid, r = mid - ;
else l = mid + ;
}
} void DP()
{
dp[][pre] = ;
for(int i = n - ; i >= ; i --)
{
if(sum[n] - sum[i] <= ans)
mark[i] = true;
else break;
}
bool flag = false;
for(int i = ; i <= m; i ++)
{
head = , tail = ;
q[++ tail] = i - , tot = dp[i - ][pre];
for(int j = i; j <= n; j ++)
{
while(head <= tail && sum[j] - sum[q[head]] > ans)
tot = (tot - dp[q[head]][pre] + mod) % mod, head ++;
dp[j][now] = tot, dp[j][now] %= mod;
if(dp[j][pre]) q[++ tail] = j, tot += dp[j][pre], tot %= mod;
if(mark[j])
{
fans += dp[j][now];
fans %= mod;
}
}
now ^= , pre ^= ;
}
} int main()
{
n = read(), m = read();
for(int i = ; i <= n; i ++)
{
a[i] = read(), sum[i] = sum[i - ] + a[i];
maxx = max(a[i], maxx);
}
solve();
cout << ans << " ";
DP();
cout <<fans << endl;
return ;
}

【题解】HAOI2008木棍分割的更多相关文章

  1. BZOJ1044: [HAOI2008]木棍分割

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

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

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

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

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

  4. HAOI2008 木棍分割 数据结构优化dp+二分答案

    很久之前打的题,现在补篇博客 打滚动数组 #E. 木棍分割 Accepted 100 1712 ms 1512 KiB   2019-05-07 17:01:23 Short 不打滚动数组 #419. ...

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

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

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

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

  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 ...

  10. BZOJ_1044_[HAOI2008]木棍分割_二分答案+DP+单调队列

    BZOJ_1044_[HAOI2008]木棍分割_二分答案+DP Description 有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个 ...

随机推荐

  1. 解决 Android sdk content loader 0%

    第一次遇到这种情况,真的很头痛,没办法 ,是问题就要解决,在网上找了一些方法,归纳了下来. 方法一(关闭后重启): 遇到Eclipse右下角一直显示“Android sdk content loade ...

  2. 基于socketserver模块实现并发的套接字(tcp、udp)

    tcp服务端:import socketserver class MyHandler(socketserver.BaseRequestHandler): def handle(self): #通信循环 ...

  3. mysql创建表时反引号的作用

    试用navicat工具查看现网mysql建表语句时,发现表名和字段名都是反引号引起来的 CREATE TABLE `tab_notice_title_tv` ( `i_id` ) NOT NULL A ...

  4. php-5.6.26源代码 - hash存储结构 - 初始化

    初始化 有指定析构函数,在销毁hash的时候会调用,如:“类似extension=test.so扩展”也是存放在HashTable中的,“类似extension=test.so扩展”的module_s ...

  5. input输入框类型

    输入大小写字母.数字.下划线: <input type="text" onkeyup="this.value=this.value.replace(/[^\w_]/ ...

  6. 【Nginx一】Nginx服务器搭建

    Nginx服务器搭建 Nginx服务器搭建 下载Nginx源码包 安装Nginx 解压Nginx安装包 安装Nginx依赖 启动Nginx 下载Nginx源码包 官网下载地址 命令:wget http ...

  7. kafka概述

    kafka概述 Apache Kafka是一个开源 消息 系统,由Scala写成.是由Apache软件基金会开发的一个开源消息系统项目. Kafka最初是由LinkedIn开发,并于2011年初开源. ...

  8. (数据科学学习手札29)KNN分类的原理详解&Python与R实现

    一.简介 KNN(k-nearst neighbors,KNN)作为机器学习算法中的一种非常基本的算法,也正是因为其原理简单,被广泛应用于电影/音乐推荐等方面,即有些时候我们很难去建立确切的模型来描述 ...

  9. 最小费用最大流模板 洛谷P3381

    题目描述 如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表 ...

  10. python2.7入门---Number(数字)

        今天咱们来简单分享一下关于python中的一种数据类型和操作方法.费话不多说哈,咱们直接来进行实践加理论.首先,我们要知道,Python Number 数据类型用于存储数.数据类型是不允许改变 ...