题目大意

网址:https://daniu.luogu.org/problemnew/show/P2511
题目大意:
有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处.
现在允许你最多砍断m个连接处,砍完后n根木棍被分成了很多段,
要求满足总长度最大的一段长度最小, 并且输出有多少种砍的方法使得总长度最大的一段长度最小.
数据范围: \(n<=50000, 0<=m<=min(n-1,1000)\).

题目解法

第一问弱智题,直接二分即.
第二问考虑DP。 显然f[i][j]表示到了第i根木棍,已经切了j次的方案数。
那么找到i木棍最远可延展距离lev[i]。显然转移为:
\[f[i][j] = ∑f[v][j-1],(Lg[v,i]<=Res)\]
但是这样子显然空间开不下。
观察到j的转移只于j-1有关,可以压掉j。然后考虑如何优化时间复杂度。
显然f[i][j]求和是可以线性记录的。令:
\[g[i][j-1] = g[i-1][j-1] +∑f[v][j-1],(Lg[v,i]<=Res)\]
那么每次转移时,一边转移f,一边修改g,这样就可以实现\(O(1)\)转移了。
最终的空间复杂度为\(O(N)\),时间复杂度为\(O(N*M)\)。

具体代码

#include<bits/stdc++.h>
#define RG register
#define IL inline
#define maxn 100005
#define mod 10007
using namespace std;

int Res,N,M,Ans,Lg[maxn],lev[maxn],f[maxn][3],g[maxn][3];

IL bool Check(RG int x){
    RG int d = 0,cnt = 0;
    for(RG int i = 1; i <= N; i ++){
        if(Lg[i] > x)return false;
        if(d + Lg[i] > x){d = Lg[i]; cnt++;}
        else d += Lg[i];
    }
    return cnt <= M;
}

int main()
{
    cin>>N>>M;
    for(RG int i = 1; i <= N; i ++)cin>>Lg[i];
    int L = 0,R = 2000000000; Res = -1;
    while(L<=R){
        RG int mid = (L+R)>>1;
        if(Check(mid)){Res = mid; R = mid - 1;}
        else L = mid + 1;
    }
    for(RG int i = 1; i <= N; i ++)Lg[i] += Lg[i-1];
    L = 1;
    for(RG int R = 1; R <= N; R ++)
        {while(Lg[R] - Lg[L-1] > Res && L<R)L++ ; lev[R] = L;}
    for(RG int i = 1; i <= N; i ++)
        f[i][0] = (Lg[i] <= Res),g[i][0] = (g[i-1][0] + f[i][0])%mod;
    Ans = (Lg[N] <= Res);
    for(RG int t = 1; t <= M; t ++){
        RG int j = t&1;
        g[0][j] = 0;
        for(RG int i = 1; i <= N; i ++){
            f[i][j] = (g[i-1][j^1] - g[lev[i]-2][j^1] + mod)%mod;
            if(i == N)Ans = (Ans + f[i][j])%mod;
            g[i][j] = g[i-1][j] + f[i][j];
        }
    }
    cout<<Res<<" "<<Ans; return 0;
}

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

  1. BZOJ1044: [HAOI2008]木棍分割

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

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

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

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

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

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

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

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

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

  6. 1044: [HAOI2008]木棍分割

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

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

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

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

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

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

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

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

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

随机推荐

  1. LeetCode - 626. Exchange Seats

    Mary is a teacher in a middle school and she has a table seat storing students' names and their corr ...

  2. Javascript获取数组中的最大值和最小值方法汇总

    方法一 sort()方法 b-a从大到小,a-b从小到大 var max2 = arr.sort(function(a,b){ return b-a; })[0]; console.log(max2) ...

  3. iOS 关于文件的操作

    最近做东西,遇到了使用文件方面的问题,花了点时间把文件研究了一下! 一  关于文件路径的生成 我用的方法是: -(NSString*)dataFilePath { NSArray * paths = ...

  4. Java经典编程题50道之十五

    输入三个整数x,y,z,请把这三个数由小到大输出. public class Example15 {    public static void main(String[] args) {       ...

  5. C语言链表的建立、插入和删除

    先看下向链表中插入节点 下面这个是删除链表节点

  6. 《android开发艺术探索》读书笔记(十二)--Bitmap的加载和Cache

    接上篇<android开发艺术探索>读书笔记(十一)--Android的线程和线程池 No1: 目前比较常用的缓存策略是LruCache和DiskLruCache,LruCache常被用作 ...

  7. uva10410 栈

    根据DFS和BFS重建树. BFS反映了当前节点到达根结点的距离,通过栈把当前处理的树或则子树的根结点放在栈顶,通过遍历DFS序列,判断当前元素与栈顶元素的关系,如果是子节点,就将它压入栈中成为新的栈 ...

  8. ZOJ - 2477 dfs [kuangbin带你飞]专题二

    注意输入的处理,旋转操作打表.递增枚举可能步数,作为限制方便找到最短路. AC代码:90ms #include<cstdio> #include<cstring> char m ...

  9. Linux sed 和 awk的用法

    sed用法: 原文链接:http://www.cnblogs.com/dong008259/archive/2011/12/07/2279897.html sed是一个很好的文件处理工具,本身是一个管 ...

  10. 转:20分钟教你使用hexo搭建github博客

    注册Github账号 这里我们就不多讲了,小伙伴们可以点击这里,进入官网进行注册. 创建仓库 图片来自Github 登录账号后,在Github页面的右上方选择New repository进行仓库的创建 ...