题目链接
https://www.lydsy.com/JudgeOnline/problem.php?id=3063
题解
显然,如果,那么可以设表示两边分别在位置,现在在左边/右边时最大的权值和。但是这样显然时的。
考虑用边来代替点,设表示上一个经过的边时,现在在左边/右边的权值和,用一个数组辅助转移。时间复杂度。
代码
#include <cstdio>
#include <algorithm>
int read()
{
int x=0,f=1;
char ch=getchar();
while((ch<'0')||(ch>'9'))
{
if(ch=='-')
{
f=-f;
}
ch=getchar();
}
while((ch>='0')&&(ch<='9'))
{
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
const int maxn=40000;
const int maxm=100000;
struct edge
{
int l,r;
bool operator <(const edge &other) const
{
if(l==other.l)
{
return r<other.r;
}
return l<other.l;
}
bool operator ==(const edge &other) const
{
return (l==other.l)&&(r==other.r);
}
};
edge e[maxm+10];
long long f[maxm+10][2],mx[maxn+10],ans;
int v[2][maxn+10],n,m,k,tot;
int main()
{
n=read();
m=read();
k=read();
for(int i=1; i<=n; ++i)
{
v[0][i]=read();
ans=std::max(ans,1ll*v[0][i]);
}
for(int i=1; i<=m; ++i)
{
mx[i]=v[1][i]=read();
ans=std::max(ans,1ll*v[1][i]);
}
for(int i=1; i<=k; ++i)
{
e[i].l=read();
e[i].r=read();
}
std::sort(e+1,e+k+1);
tot=std::unique(e+1,e+k+1)-e-1;
int now=1;
while(now<=tot)
{
long long lmx=v[0][e[now].l];
int pastnow=now;
while((now<tot)&&(e[now].l==e[now+1].l))
{
++now;
}
++now;
for(int i=pastnow; i<now; ++i)
{
f[i][0]=mx[e[i].r]+v[0][e[i].l];
ans=std::max(ans,f[i][0]);
f[i][1]=lmx+v[1][e[i].r];
mx[e[i].r]=std::max(mx[e[i].r],f[i][1]);
ans=std::max(ans,f[i][1]);
lmx=std::max(lmx,f[i][0]);
}
}
printf("%lld\n",ans);
return 0;
}