Gym - 102302 E - Chi's performance —— DP

This way

题意:

现在有n个人,第i个人有一个vi和pi。
现在按照v从小到大的顺序排序,但是v相同的话,可以自己随意组合。
如果相邻两个人的v不同的话,答案加上两个人p的差的绝对值。
问你答案最大是多少。

题解:

首先一眼想到dp,然后其实对于每种v我们只需要4个值:最大值,最小值,次大值和次小值,因为如果做差最大的话,并且只有两个端点需要考虑,所以我们只需要4个值。
所以我们对于每个v,三层for考虑当前的左端,上一个的右端以及左端。
特判一下上一个v只有1个值得情况。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e6+5;
vector<ll>vec[N];
struct people{
    int v;
    ll p;
}a[N];
int b[N];
ll val[N][4],dp[N][4];
ll dec(ll a,ll b){
    return a-b>=0?a-b:b-a;
}
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d%lld",&a[i].v,&a[i].p),b[i]=a[i].v;
    sort(b+1,b+1+n);
    int all=unique(b+1,b+1+n)-b-1;
    for(int i=1;i<=n;i++)
        a[i].v=lower_bound(b+1,b+1+all,a[i].v)-b,vec[a[i].v].push_back(a[i].p);
    memset(val,-1,sizeof(val));
    for(int i=1;i<=all;i++){
        sort(vec[i].begin(),vec[i].end());
        int siz=vec[i].size();
        val[i][0]=vec[i][0];
        if(siz>=2)
            val[i][1]=vec[i][1];
        if(siz==3)
            val[i][2]=vec[i][2];
        else if(siz>=4)
            val[i][2]=vec[i][siz-2],val[i][3]=vec[i][siz-1];
    }
    for(int i=2;i<=all;i++){
        for(int j=0;j<4&&~val[i][j];j++){
            if(val[i-1][1]==-1)
                dp[i][j]=max(dp[i][j],dp[i-1][0]+dec(val[i][j],val[i-1][0]));
            else{
                for(int en=0;en<4&&~val[i-1][en];en++){
                    for(int sta=0;sta<4&&~val[i-1][sta];sta++){
                        if(sta==en)
                            continue;
                        dp[i][j]=max(dp[i][j],dp[i-1][sta]+dec(val[i-1][en],val[i][j]));
                    }
                }
            }
        }
    }
    ll ans=0;
    for(int i=0;i<4;i++)
        ans=max(ans,dp[all][i]);
    printf("%lld\n",ans);
    return 0;
}
/**/
发布了530 篇原创文章 · 获赞 31 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/tianyizhicheng/article/details/104227241