zoukankan      html  css  js  c++  java
  • [BZOJ 2151]种树

    Description

    题库链接

    给你一个长度为 (n) 的环状序列,每一个位置有一定权值,让你选出恰好 (m) 个位置,使得选出的位置两两不相邻并且权值和最大。求最大权值和。

    (1leq nleq 200000)

    Solution

    [APIO/CTSC 2007]数据备份有点类似。

    (g(x)) 为恰好选 (x) 个位置时,最大的权值和。可以发现 (g(x)) 是上凸的。因此考虑带权二分。二分上下界取位置上的权值最值。

    (f_{i,1/0,1/0}) 为第一个位置选或不选,第 (i) 个位置选或不选获得的最大权值和。DP 只需考虑 (i)(i-1) 这两个位置选取与否。

    对于 (g) 函数可能存在相邻若干点斜率相同的情况,还是和上一题一样的做法,转移时记录最少选点数。之后每次二分到选点数 (leq m) 的值时更新答案。

    Code

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 200000+5, inf = 1e9;
    
    int n, m, f[N][2][2], a[N], g[N][2][2], tmp;
    
    bool check(int mid) {
        f[1][1][1] = a[1]-mid, g[1][1][1] = 1;
        f[1][0][0] = 0, g[1][0][0] = 0;
        f[1][1][0] = f[1][0][1] = -inf;
        for (int i = 2; i <= n; i++)
            for (int j = 0; j <= 1; j++) {
                f[i][j][1] = f[i-1][j][0]+a[i]-mid;
                g[i][j][1] = g[i-1][j][0]+1;
                if (f[i-1][j][0] > f[i-1][j][1] || (f[i-1][j][0] == f[i-1][j][1] && g[i-1][j][0] < g[i-1][j][1]))
                    f[i][j][0] = f[i-1][j][0], g[i][j][0] = g[i-1][j][0];
                else f[i][j][0] = f[i-1][j][1], g[i][j][0] = g[i-1][j][1];
            }
        int mf = -inf, mg = 0;
        for (int i = 0; i <= 1; i++)
            for (int j = 0; j <= 1; j++)
                if (!(i&j))
                    if (f[n][i][j] > mf || (f[n][i][j] == mf && g[n][i][j] < mg))
                        mf = f[n][i][j], mg = g[n][i][j];
        tmp = mf+m*mid;
        return mg <= m;
    }
    int main() {
        scanf("%d%d", &n, &m);
        if (n/2 < m) {puts("Error!"); return 0; }
        for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
        int l = -1000, r = 1000, ans = -1, mid;
        while (l <= r) {
            mid = (l+r)>>1;
            if (check(mid)) r = mid-1, ans = tmp;
            else l = mid+1;
        }
        printf("%d
    ", ans);
        return 0;
    }
  • 相关阅读:
    POI实现Excel导入数据库数据
    POI对Excel进行读取操作,工具类,便于操作数据
    HAProxy-1.8.20 根据后缀名转发到后端服务器
    Haproxy-1.8.20 编译安装:
    Soat控制HaProxy 动态增减服务器
    Haproxy-1.8.20 根据路径(URI)转发到后端不同集群
    Ansible User 模块添加单用户并ssh-key复制
    Ansible-playbook 安装redis
    二进制安装mysql-5.7.28
    编译安装 nginx -1.14.2
  • 原文地址:https://www.cnblogs.com/NaVi-Awson/p/13515254.html
Copyright © 2011-2022 走看看