題名
回答
守っ| CI - CJ | \ lvert C_I-c_j \ rvert∣ c私−cJ∣、設定<j i <j私<j、結果はバイナリ表現[i、j − 1] [i、j-1]です。[私、j−1 ]ビットは111つの番号;次に異なる(i、j)(i、j)(私は、j )対、∣ ci − cj ∣ \ lvert c_i-c_j \ rvert∣ c私−cJ∣値が異なります。状態がパスの終点とパスの上端で取得できる最大値で構成される2タプルとして表される場合は、∣ ci − cj ∣ \ lvert c_i-c_j \ rvertを使用します。∣ c私−cJ|Connect取得、その後、エッジの権利のためのエッジをDAG DAGをD A Gであり、パス上のエッジの重みは単調に増加します。
dp [i] [k] dp [i] [k] d p [ i ] [ k ]は、iiのパスを表しますiは終点であり、道路の重量で取ることができる最大値はkkです。kの場合、取得できるポイントの最大数。ましょう、K = | CI - CJ | K = \ lvert C_I-c_j \ rvertk=∣ c私−cJ∣、ANDtagi≠tagj tag_i \ neq tag_jt a g私=t a gJ设设(k)に対する(k)に対するp r e (k )がkk未満k的最大边権利、则有{dp [i] [k] = max
{dp [i] [pre(k)]、dp [j] [pre(k)] + ∣ ci − cj∣} dp [ j] [k] =max{dp [j] [pre(k)]、dp [i] [pre(k)] + ∣ ci − cj ∣} \ begin {cases} dp [i] [k] = \ max \ {dp [i] [pre(k)]、dp [j] [pre(k)] + \ lvert c_i-c_j \ rvert \} \\ dp [j] [k] = \ max \ {dp [j] [pre(k)]、dp [i] [pre(k)] + \ lvert c_i-c_j \ rvert \} \ end {cases}{{
d p [ i ] [ k ]=max {
d p [ i ] [ p r e (k )] 、d p [ j ] [ p r e (k )]+∣ c私−cJ∣ }d p [ j ] [ k ]=max {
d p [ j ] [ p r e (k )] 、d p [ i ] [ p r e (k )]+∣ c私−cJ| }DP DP経路上で選択することができ、エッジ重みの昇順にD P、即数(1≤i≤n)i(1 \ leq i \ leq n)i (1≤私≤n )递增、j(1≤j≤i−1)j(1 \ leq j \ leq i-1)j (1≤j≤私−1 )減少;一次元DPDPへの圧縮を実現D P。最後に、パスの終わりを列挙し、答えを更新します。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 5005;
int T, N, tag[maxn], s[maxn];
ll dp[maxn];
int main()
{
scanf("%d", &T);
while (T--)
{
scanf("%d", &N);
for (int i = 1; i <= N; ++i)
scanf("%d", tag + i);
for (int i = 1; i <= N; ++i)
scanf("%d", s + i);
memset(dp, 0, sizeof(dp));
for (int i = 1; i <= N; ++i)
for (int j = i - 1; j; --j)
{
if (tag[i] == tag[j])
continue;
ll xi = dp[i], xj = dp[j], d = abs(s[i] - s[j]);
dp[i] = max(dp[i], xj + d), dp[j] = max(dp[j], xi + d);
}
printf("%lld\n", *max_element(dp + 1, dp + N + 1));
}
return 0;
}