• BZOJ3594: [Scoi2014]方伯伯的玉米田【二维树状数组优化DP】


    Description

    方伯伯在自己的农田边散步,他突然发现田里的一排玉米非常的不美。
    这排玉米一共有N株,它们的高度参差不齐。
    方伯伯认为单调不下降序列很美,所以他决定先把一些玉米拔高,再把破坏美感的玉米拔除掉,使得剩下的玉米的高度构成一个单调不下降序列。
    方伯伯可以选择一个区间,把这个区间的玉米全部拔高1单位高度,他可以进行最多K次这样的操作。拔玉米则可以随意选择一个集合的玉米拔掉。
    问能最多剩多少株玉米,来构成一排美丽的玉米。

    Input

    第1行包含2个整数n,K,分别表示这排玉米的数目以及最多可进行多少次操作。
    第2行包含n个整数,第i个数表示这排玉米,从左到右第i株玉米的高度ai。

    Output

    输出1个整数,最多剩下的玉米数。

    Sample Input

    3 1
    2 1 3

    Sample Output

    3

    HINT

    1 < N < 10000,1 < K ≤ 500,1 ≤ ai ≤5000


    思路

    首先发现一个性质:因为要保证单调不降,所以右端点取n是最优的

    然后就可以用(dp_{i,j})表示修改后值是i的数加了j次
    这个状态比较神奇
    可以发现是可以从任何(k le i, p le j)(dp_{k,p})转移过来的
    然后就二维树状数组优化了


    //Author: dream_maker
    #include<bits/stdc++.h>
    using namespace std;
    //----------------------------------------------
    //typename
    typedef long long ll;
    //convenient for
    #define fu(a, b, c) for (int a = b; a <= c; ++a)
    #define fd(a, b, c) for (int a = b; a >= c; --a)
    #define fv(a, b) for (int a = 0; a < (signed)b.size(); ++a)
    //inf of different typename
    const int INF_of_int = 1e9;
    const ll INF_of_ll = 1e18;
    //fast read and write
    template <typename T>
    void Read(T &x) {
      bool w = 1;x = 0;
      char c = getchar();
      while (!isdigit(c) && c != '-') c = getchar();
      if (c == '-') w = 0, c = getchar();
      while (isdigit(c)) {
        x = (x<<1) + (x<<3) + c -'0';
        c = getchar();
      }
      if (!w) x = -x;
    }
    template <typename T>
    void Write(T x) {
      if (x < 0) {
        putchar('-');
        x = -x; 
      }
      if (x > 9) Write(x / 10);
      putchar(x % 10 + '0');
    }
    //----------------------------------------------
    const int N = 1e4 + 10;
    const int K = 5e2 + 10;
    #define lowbit(p) (p & (-p)) 
    int t[N + K][K];
    int n, k, a[N];
    int query(int x, int y) {
      int res = 0;
      int nx = x;
      while (nx) {
        int ny = y;
        while (ny) {
          res = max(res, t[nx][ny]);
          ny -= lowbit(ny);
        }
        nx -= lowbit(nx);
      }
      return res;
    }
    void update(int x, int y, int vl) {
      int nx = x;
      while (nx < N + K) {
        int ny = y;
        while (ny < K) {
          t[nx][ny] = max(t[nx][ny], vl);
          ny += lowbit(ny);
        }
        nx += lowbit(nx);
      }
    }
    int main() {
      Read(n), Read(k); ++k;
      fu(i, 1, n) Read(a[i]);
      int ans = 0;
      fu(i, 1, n) {
        fd(j, k, 1) {
          int dp = query(a[i] + j, j) + 1;
          ans = max(ans, dp);
          update(a[i] + j, j, dp);
        }
      }
      Write(ans);
      return 0;
    }
    
  • 相关阅读:
    c++静态变量和静态函数
    c++抽象类和纯虚函数
    二维矩阵的算法
    JS操作CSS样式
    DOM
    JavaScript学习
    CSS样式表介绍
    HTML 学习整理
    ADO.Net知识总结
    数据库表查询高级 触发器游标等
  • 原文地址:https://www.cnblogs.com/dream-maker-yk/p/9769102.html
Copyright © 2020-2023  润新知