zoukankan      html  css  js  c++  java
  • P2511 [HAOI2008]木棍分割

    Description

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

    Solution

    二分答案+动态规划

    Code

    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <algorithm>
    
    const int mod = 10007;
    const int N = 50005;
    int l[N];
    
    bool judge(int lim, int n, int m) {
        int used = 0, sig = 0;
        for (int i = 1; i <= n; i += 1) {
            if (sig + l[i] <= lim) sig += l[i];
            else sig = l[i], used += 1;
        }
        return used <= m;
    }
    
    int s[N], p[N];
    int f1[N], f2[N];
    int get(int L, int n, int m) {
        for (int i = 1; i <= n; i += 1)
            s[i] = s[i - 1] + l[i];
        for (int i = 1; i <= n; i += 1)
            p[i] = std:: lower_bound(s, s + n + 1, s[i] - L) - s;
        int *f = f1, *g = f2;
        for (int i = 0; i <= n; i += 1) g[i] = 1;
        int res = 0;
        for (int i = 1; i <= m + 1; i += 1) {
            for (int j = 1; j <= n; j += 1) {
                f[j] = (g[j - 1] - g[p[j] - 1]) % mod;
            }
            res = (res + f[n]) % mod;
            f[0] = 0;
            for (int j = 1; j <= n; j += 1)
                f[j] = (f[j - 1] + f[j]) % mod;
            std:: swap(f, g);
        }
        return (res + mod) % mod;
    }
    
    int main () {
        int n, m, Mx = 0, Ma = 0;
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= n; i += 1)
            scanf("%d", &l[i]), Mx += l[i], Ma = std:: max(Ma, l[i]);
        int l = Ma, r = Mx, mid;
        while (l <= r) {
            mid = l + r >> 1;
            if (judge(mid, n, m)) r = mid - 1;
            else l = mid + 1;
        }
        printf("%d ", l);
        printf("%d
    ", get(l, n, m));
        return 0;
    }
    
  • 相关阅读:
    Cache Miss
    EmmyLua 注解标记总结
    关于浮点数计算时的精度问题 0.1+0.2不等于0.3
    Git-原理相关归纳-非入门
    读《非暴力沟通》
    Unity-图片压缩格式
    Git-大小写的坑
    将当前系统中的进程信息打印到文件中
    g++用法
    C++文本文件读写操作
  • 原文地址:https://www.cnblogs.com/qdscwyy/p/9813486.html
Copyright © 2011-2022 走看看