DP - 类似LIS
这题虽然说要上升子序列,但只需要长度为 3 3 3 的,所以我们不需要求 LIS 的长度,只用求费用
设
f
[
i
]
[
j
]
f[i][j]
f[i][j] 表示以第
i
i
i 个元素结尾的,长度为
j
j
j 的上升子序列的最小费用(
j
≤
3
j \le 3
j≤3)
则
f
[
i
]
[
j
]
=
m
i
n
{
f
[
k
]
[
j
−
1
]
+
c
[
i
]
}
(
a
[
k
]
<
a
[
i
]
)
,
(
k
<
i
)
f[i][j]=min\{ f[k][j-1]+c[i] \}(a[k]<a[i]),(k<i)
f[i][j]=min{f[k][j−1]+c[i]}(a[k]<a[i]),(k<i)
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int Maxn=3010,inf=0x3f3f3f3f;
int a[Maxn],c[Maxn];
int f[Maxn][5];
int n,ans=inf;
inline int read()
{
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0' && ch<='9')s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
return s*w;
}
int main()
{
// freopen("in.txt","r",stdin);
n=read();
for(int i=1;i<=n;++i)
a[i]=read();
memset(f,inf,sizeof(f));
for(int i=1;i<=n;++i)
{
c[i]=read();
f[i][1]=c[i];
}
for(int i=1;i<=n;++i)
{
for(int j=1;j<i;++j)
{
if(a[j]>=a[i])continue;
f[i][2]=min(f[i][2],f[j][1]+c[i]);
f[i][3]=min(f[i][3],f[j][2]+c[i]);
}
ans=min(ans,f[i][3]);
}
if(ans==inf)puts("-1");
else printf("%d\n",ans);
return 0;
}