• BZOJ 5125: [Lydsy1712月赛]小Q的书架


    5125: [Lydsy1712月赛]小Q的书架
    思路:
    分治优化决策单调性dp
    代码:

    #pragma GCC optimize(2)
    #pragma GCC optimize(3)
    #pragma GCC optimize(4)
    #include<bits/stdc++.h>
    using namespace std;
    #define y1 y11
    #define fi first
    #define se second
    #define pi acos(-1.0)
    #define LL long long
    //#define mp make_pair
    #define pb push_back
    #define ls rt<<1, l, m
    #define rs rt<<1|1, m+1, r
    #define ULL unsigned LL
    #define pll pair<LL, LL>
    #define pli pair<LL, int>
    #define pii pair<int, int>
    #define piii pair<pii, int>
    #define pdd pair<double, double>
    #define mem(a, b) memset(a, b, sizeof(a))
    #define debug(x) cerr << #x << " = " << x << "
    ";
    #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    //head
    
    const int N = 4e4 + 10;
    const int INF = 0x3f3f3f3f;
    int dp[N][11], s[N][11], a[N], bit[N], n, k, tot, l, r;
    inline void add(int x, int a) {
        while(x <= n) bit[x] += a, x += x&-x;
    }
    inline int sum(int x) {
        int ans = 0;
        while(x) ans += bit[x], x -= x&-x;
        return ans;
    }
    inline void move(int L, int R) {
        while(l < L) add(a[l++], -1), tot -= sum(a[l-1]-1);
        while(l > L) add(a[--l], 1), tot += sum(a[l]-1);
        while(r < R) add(a[++r], 1), tot += r-l+1-sum(a[r]);
        while(r > R) add(a[r--], -1), tot -= r-l+1-sum(a[r+1]);
    }
    void solve(int L, int R, int l, int r, int k) {
        if(L > R) return ;
        int mid = L+R >> 1, up = min(mid-1, r), id = up;
        dp[mid][k] = INF;
        for (int i = up; i >= l; --i) {
            move(i+1, mid);
            if(dp[i][k-1] + tot < dp[mid][k]) {
                dp[mid][k] = dp[i][k-1] + tot;
                id = i;
            }
        }
        solve(L, mid-1, l, id, k);
        solve(mid+1, R, id, r, k);
    }
    int main() {
        scanf("%d %d", &n, &k);
        for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
        for (int i = 1; i <= n; ++i) dp[i][0] = INF;
        l = 1, r = 0;
        for (int i = 1; i <= k; ++i) solve(1, n, 0, n-1, i);
        printf("%d
    ", dp[n][k]);
        return 0;
    }
    
    
  • 相关阅读:
    Perl-晶晨2021届笔试题
    数字IC设计流程
    后端一些常考知识点
    sklearn: 利用TruncatedSVD做文本主题分析
    用截断奇异值分解(Truncated SVD)降维
    numpy.linalg.norm(求范数)
    岭回归和lasso回归及正则化
    什么是范数?
    MySQL三大范式和反范式
    汇编知识之EIP寄存器
  • 原文地址:https://www.cnblogs.com/widsom/p/11498369.html
Copyright © 2020-2023  润新知