zoukankan      html  css  js  c++  java
  • gym102302E_Chi's performance

    题意

    给n个二元组(v,p),要求排序使得v从小到大,而且总价值最大,价值定义为相邻两个v值不同的p值之差绝对值之和。

    分析

    • in a row原来是相邻的意思。
    • 对于每个相同v值的块来说,有用的数只有最大,次大,最小,次小,且如果块大小小于4,还有一些会重复,后面需要特判。
    • 所以直接dp到每个块,左端点放哪个数,右端点放哪个数能获得的最大价值。
    • 特判块大小为1的情况,以及上一个块大小为1的情况。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=1e6+50;
    struct node{
        int v,p;
        bool operator<(const node& rhs)const{
            if(v==rhs.v){
                return p<rhs.p;
            }else{
                return v<rhs.v;
            }
        }
    }a[N];
    ll dp[N][5];
    int mx[N][5],sz[N],num[N];
    int n;
    vector<int> v;
    int main(){
    //    freopen("in.txt","r",stdin);
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d%d",&a[i].v,&a[i].p);
            v.push_back(a[i].v);
        }
        sort(v.begin(),v.end());
        v.erase(unique(v.begin(),v.end()),v.end());
        for(int i=1;i<=n;i++){
            a[i].v=lower_bound(v.begin(),v.end(),a[i].v)-v.begin()+1;
        }
        sort(a+1,a+1+n);
        int t=1;
        vector<int> tp;
        tp.push_back(a[1].p);
        for(int i=2;i<=n;i++){
            if(a[i].v==a[i-1].v){
                t++;
                tp.push_back(a[i].p);
            }else{
                sz[a[i-1].v]=t;
                if(t>=2){
                    mx[a[i-1].v][3]=tp[t-1];
                    mx[a[i-1].v][2]=tp[t-2];
                    mx[a[i-1].v][1]=tp[1];
                    mx[a[i-1].v][0]=tp[0];
                }else{
                    num[a[i-1].v]=a[i-1].p;
                }
                t=1;
                tp.clear();
                tp.push_back(a[i].p);
            }
        }
        sz[a[n].v]=t;
        if(t>=2){
            mx[a[n].v][3]=tp[t-1];
            mx[a[n].v][2]=tp[t-2];
            mx[a[n].v][1]=tp[1];
            mx[a[n].v][0]=tp[0];
        }else{
            num[a[n].v]=a[n].p;
        }
        int vs=v.size();
        for(int i=2;i<=vs;i++){
            if(sz[i]==1){
                for(int j=0;j<=3;j++){
                    if(sz[i-1]==1){
                        dp[i][j]=dp[i-1][0]+abs(num[i]-num[i-1]);
                    }else{
                        for(int l=0;l<=3;l++){
                            dp[i][j]=max(dp[i][j],dp[i-1][l]+abs(num[i]-mx[i-1][l]));
                        }
                    }
                }
            }else{
                if(sz[i-1]==1){
                    for(int j=0;j<=3;j++){
                        for(int k=0;k<=3;k++){
                            if(j==k || (sz[i]==2 && (j+k==2 || j+k==4)) || (sz[i]==3 && ( (j && k) && (j+k==3)))){
                                continue;
                            }
                            dp[i][j]=max(dp[i][j],dp[i-1][0]+abs(mx[i][k]-num[i-1]));
                        }
                    }
                }else{
                    for(int j=0;j<=3;j++){
                        for(int k=0;k<=3;k++){
                            if(j==k || (sz[i]==2 && (j+k==2 || j+k==4)) || (sz[i]==3 && ( (j && k) && (j+k==3)))){
                                continue;
                            }
                            for(int l=0;l<=3;l++){
                                dp[i][j]=max(dp[i][j],dp[i-1][l]+abs(mx[i][k]-mx[i-1][l]));
                            }
                        }
                    }
                }
            }
        }
        ll ans=0;
        for(int i=0;i<=3;i++){
            ans=max(ans,dp[vs][i]);
        }
        printf("%lld
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    hbase 得到一行的数据详情
    文件上传
    es 启动用户
    es 分片丢失
    es 调整查询窗口
    hbase 字段值开头查询
    maven 项目linux运行可执行jar
    hbase count 扫表查询
    hbase 查询空串空字段
    sql常用手法(二)
  • 原文地址:https://www.cnblogs.com/zxcoder/p/11816232.html
Copyright © 2011-2022 走看看