• [HAOI2008]木棍分割


    二分答案限制最大的多少,然后再DP一下

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
     
    const int Dollar1 = 10007;
    const int MAXN = 50010;
    inline int up(int x) { return x -= Dollar1, x + (x >> 31 & Dollar1); }
    inline int down(const int x) { return x + (x >> 31 & Dollar1); }
    int li[MAXN], n, m;
    int solve(int x) {
        int cnt = 0, now = 0;
        for (int i = 1; i <= n; ++i) {
            if (now + li[i] > x) {
                now = 0;
                ++cnt;
            }
            now += li[i];
        }
        return cnt + !!now;
    }
    int f[2][MAXN];
    int main() {
        scanf("%d%d", &n, &m); ++m;
        int l = 1, r = 50000000, ans = 0;
        for (int i = 1; i <= n; ++i) scanf("%d", li + i), l = std::max(l, li[i]);
        while (l <= r) {
            int mid = l + r >> 1;
            if (solve(mid) <= m) r = mid - 1, ans = mid;
            else l = mid + 1;
        }
        printf("%d ", ans);
        int now = 1, lst = 0;
        f[now][0] = 1;
        int Ans = 0;
        for (int T = 1; T <= m; ++T) {
            std::swap(now, lst);
            memset(f[now], 0, sizeof f[now]);
            int lcur = 0, nx = 0, cnt = f[lst][0];
            for (int j = 1; j <= n; ++j) {
                nx += li[j]; 
                while (nx > ans) {
                    cnt = down(cnt - f[lst][lcur]);
                    nx -= li[++lcur];
                }
                if (lcur < j) f[now][j] = cnt;
                cnt = up(cnt + f[lst][j]);
            }
            Ans = up(Ans + f[now][n]);
        }
        printf("%d
    ", Ans);
        return 0;
    }
    
  • 相关阅读:
    DataTableToJSON
    css hack
    把网络数据流转换成图片类
    递归(转)
    SQL 锁
    观察者
    yield
    开闭原则(转)
    迪米特法则(最少知道原则)(转)
    sql 游标
  • 原文地址:https://www.cnblogs.com/daklqw/p/10361531.html
Copyright © 2020-2023  润新知