/* 用dp[i][j]来表示a[i]将要匹配b[j]时的代价 如果a[i]没有对应的b[x] 如果p[i]<=0,直接将这位丢掉,dp[i][j]=dp[i-1][j]+p[i] 如果p[i]>0, 那么这位能不丢就不丢, 对于所有的b[j]>a[i],a[i]不丢掉是不会影响第j位的匹配的,dp[i][j]=dp[i-1][j] 对于所有b[j]<=a[i],a[i]必须丢掉,所以 dp[i][j]=dp[i-1][j]+p[i] 如果a[i]对应了b[x] 可以发现,多了一种转移出来 dp[i][x+1]=dp[i-1][x],其它转移都是不会变的 所以把dp[i-1][x]的值提前记录下来,然后在线段树更新完后再去用这个值更新dp[i][x+1] */ #include<bits/stdc++.h> using namespace std; #define N 500005 #define ll long long ll n,a[N],p[N],m,b[N]; const ll INF = 1e16; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 ll mi[N<<2],lazy[N<<2]; void pushdown(int rt){ if(lazy[rt]!=0){ lazy[rt<<1]+=lazy[rt]; lazy[rt<<1|1]+=lazy[rt]; mi[rt<<1]+=lazy[rt]; mi[rt<<1|1]+=lazy[rt]; lazy[rt]=0; } } void update1(int L,int R,ll v,int l,int r,int rt){// 区间加 if(L>R)return; if(L<=l && R>=r){ lazy[rt]+=v;mi[rt]+=v; return; } pushdown(rt); int m=l+r>>1; if(L<=m)update1(L,R,v,lson); if(R>m)update1(L,R,v,rson); mi[rt]=min(mi[rt<<1],mi[rt<<1|1]); } void update2(int pos,ll v,int l,int r,int rt){// 单点取min if(l==r){ mi[rt]=min(mi[rt],v);return; } pushdown(rt); int m=l+r>>1; if(pos<=m)update2(pos,v,lson); else update2(pos,v,rson); mi[rt]=min(mi[rt<<1],mi[rt<<1|1]); } ll query(int pos,int l,int r,int rt){// 单点查询 if(l==r)return mi[rt]; pushdown(rt); int m=l+r>>1; if(pos<=m)return query(pos,lson); else return query(pos,rson); } int main(){ cin>>n; for(int i=1;i<=n;i++)scanf("%lld",&a[i]); for(int i=1;i<=n;i++)scanf("%lld",&p[i]); cin>>m; for(int i=1;i<=m;i++)scanf("%lld",&b[i]); update1(2,m+1,INF,1,m+1,1);//dp[0][1]=0 for(int i=1;i<=n;i++){ int x=lower_bound(b+1,b+1+m,a[i])-b; if(x==m+1){ // a[i]必须删 update1(1,m+1,p[i],1,m+1,1); } else { ll tmp=INF; if(a[i]==b[x])tmp=query(x,1,m+1,1); if(p[i]<0) update1(1,m+1,p[i],1,m+1,1); else update1(1,x,p[i],1,m+1,1); if(a[i]==b[x] && tmp<INF) update2(x+1,tmp,1,m+1,1); } } ll res=query(m+1,1,m+1,1); if(res<1e15){ puts("YES");cout<<res; }else { puts("NO"); } }