F. Strange Function(Educational Codeforces Round 85 (Rated for Div. 2))

傳送門

題意:給兩個數組ai和bi,刪除ai中元素需要花費pi的代價,bi是一個嚴格遞增序列,問你將ai刪爲bi的最小1花費代價。

題解:開一個dp數組代表bi匹配到當前位的最小代價,由於bi是一個嚴格遞增序列,所以ai對應唯一一個bi的匹配位置,所以用dp降爲一維,dp[k]由dp[k-1]推出,即刪除大於bi[k-1]的數,同時由於要求最小代價所以還應將小於等於bi[k-1]的負數也刪除,同時dp[k]如果已經被匹配了,需要將dp[k]的右限更新(原本dp[k]的右限是本身),對於需要計數的兩個數可以用樹狀數組+兩個數組維護,具體看代碼,最後就是bi[m]不一定匹配到ai的最後一位,所以還需要計算一次兩個的值。

ac代碼:

#include<stdio.h>
#include<vector>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<math.h>
#include<queue>
#include<set>
#include<map>
#include<stack>
#define ll long long
#define fo(n) for(int i=1;i<=n;i++)
#define fol(n) for(int i=n;i>=1;i--)
#define foj(i,n) for(int j=i;j<=n;j++)
#define fok(i,j) for(int k=i;k<=j;k++)
#define oui(i) printf("%d\n",i)
#define oul(i) printf("%lld\n",i)
#define sc(n) scanf("%d",&n)
#define scl(n) scanf("%lld",&n)
#define mid ((l+r)>>1)
using namespace std;
int read(){
    char c;int x=0,y=1;while(c=getchar(),(c<'0'||c>'9')&&c!='-');
    if(c=='-') y=-1;else x=c-'0';while(c=getchar(),c>='0'&&c<='9')
        x=x*10+c-'0';return x*y;
}
const int maxn=5e5+10;
const int mod=1e9+7;
const ll inf=-1e18;
int ai[maxn],bi[maxn],wi[maxn],pi[maxn];
ll dp[maxn],del[maxn],de[maxn];
int dp1[maxn];
struct node {
    ll tree[maxn];
    int lowbit(int x){return x&(-x);}
    void add(int x,ll va){
        while(x<maxn) tree[x]+=va,x+=lowbit(x);
    }
    ll query(int x){
        ll ans=0;
        while(x>0) ans+=tree[x],x-=lowbit(x);
        return ans;
    }
}A,B;
int main( ){
    int n=read();
    dp[0]=bi[0]=dp1[0]=de[0]=del[0]=0;
    for(int a=1;a<=n;a++) ai[a]=read(),wi[a]=-1;
    for(int a=1;a<=n;a++) {pi[a]=read();}
    int m=read();
    for(int a=1;a<=m;a++){bi[a]=read();wi[bi[a]]=a;dp[a]=inf,del[a]=de[a]=0;}
    ll su=0;
    for(int a=1;a<=n;a++) {
        int k=wi[ai[a]];
        if(k!=-1&&dp[k-1]!=inf){
            ll ans=su-A.query(bi[k-1])-de[dp1[k-1]],ans2=0,ans3=0;
            ll ans1=B.query(bi[k-1])-del[dp1[k-1]];
            if(dp[k]!=inf) {
                ans2 =su-A.query(bi[k]) - de[dp1[k]];
                ans3=B.query(bi[k])-del[dp1[k]]+min(0,pi[a]);
            }
            if(dp[k]==inf||dp[k-1]+ans+ans1<dp[k]+ans2+ans3){
                dp[k]=dp[k-1]+ans+ans1;
                dp1[k]=a;
                de[a]=su-A.query(ai[a]);
                del[a]=B.query(ai[a])+min(0,pi[a]);
            }
        }
        su+=pi[a];
        A.add(ai[a],pi[a]);
        if(pi[a]<0) B.add(ai[a],pi[a]);
    }
    if(dp[m]==inf){printf("NO\n");return 0;}
    ll ans=dp[m]+(su-A.query(bi[m])-de[dp1[m]])+B.query(bi[m])-del[dp1[m]];
    printf("YES\n%lld\n",ans);
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章