題意:給兩個數組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);
}