zoukankan      html  css  js  c++  java
  • 2019牛客暑期多校训练营(第十场)J

    传送门

    题意

    (n) 个 宽度为(w_i),高为(h_i) 的 木块,要求分成 k 组,对于每组内的所有木块,高度都变为组内最低木块的高度,宽度保持不变,求变化的最小面积。

    分析

    高度比较高的木块为迁就高度比较低的,所以按照高度从高到低排序

    如果设(d[i][k]) 为前 (i) 个分成 k 份可以保留的最大面积,那么答案就是 (tot-d[n][k])(tot) 初始总面积)

    考虑如何转移

    (d[i][k] = max(d[j][k-1] + (pre[i]-pre[j]) * h[i]))

    其中(pre)为宽度前缀和,即(pre[i] = sum_1^iw[i])

    暴力转移复杂度较高,考虑如何优化。(这不就是个斜率优化嘛)

    (j_1<j_2 < i)

    当满足(d[j_1][k-1]+(pre[i]-pre[j_1])*h[i] < d[j_2][k-1] + (pre[i]-pre[j_2])*h[i]) 时,(j_1) 可以从决策集中被删去,因为后者的(j_2 要比 j_1) 更优。

    上式可以化简为(h[i]<{d[j_2][k-1]-d[j_1][k-1]over pre[j_2]-pre[j_1]})

    又因为(h[i]) 是随着 (i) 单调递减的(因为前面按照高度排了序),所以当前 (i) 更新了答案之后,后面的 (i+1,i+2cdots) 它们的(h) 会越来越小,所以需要维护一个斜率单调递减的决策集

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N = 5050;
    const int K = 2020;
    struct node{
        ll w,h;
    }a[N];
    bool cmp(node a,node b){
        return a.h > b.h;
    }
    int n,k;
    ll pre[N];
    ll d[N][K];
    int q[N],l,r;
    long double slope(int x,int y,int p){
        return (long double)1.0 * (d[x][p-1] - d[y][p-1]) / (pre[x] - pre[y]);
    }
    int main(){
        scanf("%d%d",&n,&k);
        ll sum = 0;
        for(int i=1;i<=n;i++){
            scanf("%lld%lld",&a[i].w,&a[i].h);
            sum += a[i].h * a[i].w;
        }
        sort(a+1,a+1+n,cmp);
        for(int i=1;i<=n;i++)pre[i] = pre[i-1] + a[i].w;
        for(int p = 1;p <= k; p++){
            l = r = 0;
            for(int i=1;i <= n;i++){
                while(l < r && slope(q[l],q[l+1],p) >= a[i].h){
                    l++;
                }
                int j = q[l];
                d[i][p] = d[j][p-1] + a[i].h * (pre[i] - pre[j]);
                while(l < r && slope(q[r],q[r-1],p) <= slope(q[r],i,p))r--;
                q[++r] = i;
            }
        }
        printf("%lld
    ",sum-d[n][k]);
        return 0;
    }
    
  • 相关阅读:
    集合 Subset Sums
    resin config 中文(resin.xml)
    resin4 简单学习
    什么是敏捷软件测试
    10个热门IT证书
    LoadRunner监控Linux服务器
    Agile 敏捷开发
    戴明PDCA方法
    【转】什么是内存泄露? 内存泄露检测工具
    LoadRunner常见问题
  • 原文地址:https://www.cnblogs.com/1625--H/p/11380129.html
Copyright © 2011-2022 走看看