Problem Statement
There are N balls lined up in a row.
The i-th ball from the left is of color Ciand has a value of
V
i
V_i
Vi. Takahashi wants to remove exactly K balls from this row so that no two adjacent balls have the same color when arranging the remaining balls without changing the order. Additionally, under that condition, he wants to maximize the total value of the balls remaining in the row.
Determine if Takahashi can remove K balls so that no two adjacent balls in the remaining row have the same color. If it is possible, find the maximum possible total value of the remaining balls.
Constraints
1
≤
K
<
N
≤
2
×
1
0
5
1 \leq K < N \leq 2×10^5
1≤K<N≤2×105
K
≤
500
K \leq 500
K≤500
1
≤
C
i
≤
N
1 \leq C_i \leq N
1≤Ci≤N
1
≤
V
i
≤
1
0
9
1 \leq V_i \leq 10^9
1≤Vi≤109
All input values are integers.
思路
使用动态规划,在遍历到第i个球时,令dp[k][r][0/1]表示当前丢弃k个球后,第r大值对应的颜色(dp[k][r][0])及值(do[k][r][1])。注意过程中需要保证dp[k][0][0]!=dp[k][1][0],即第一个最大值对应的颜色与第二个最大值对应的颜色不相同。
Code
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
ll dp[505][2][2]; // k、c1/c2、颜色/值
const ll inf = 1e18;
int main() {
int n,k;
cin>>n>>k;
int c,v;
// 初始化
dp[0][0][0] = -1;
dp[0][1][0] = -2;
dp[0][0][1] = 0;
dp[0][1][1] = -inf;
for (int i=1;i<=k;i++) {
dp[i][0][0] = -1;
dp[i][1][0] = -2;
dp[i][0][1] = dp[i][1][1] = -inf;
}
for (int i=1;i<=n;i++) {
cin>>c>>v;
for (int j=k;j>=1;j--) { // 逆序,dp[i]会使用到dp[i-1]
// 选择第i个ball
if (dp[j][0][0]!=c) {
dp[j][0][0] = c;
dp[j][0][1] += v;
} else
dp[j][0][1] = dp[j][1][1]+v;
dp[j][1][0] = -2;
dp[j][1][1] = -inf;
// 不选择第i个ball
if (dp[j-1][1][1]>=dp[j][0][1]) { // j-1|0 >= j-1|1 >= j|0 >= j|1
dp[j][0][0] = dp[j-1][0][0];
dp[j][0][1] = dp[j-1][0][1];
dp[j][1][0] = dp[j-1][1][0];
dp[j][1][1] = dp[j-1][1][1];
} else if (dp[j-1][0][1]>=dp[j][0][1]) { // j-1|0 > j|0
if (dp[j][0][0]!=dp[j-1][0][0]) { // j|1的颜色与j-1|0的颜色不相同,则j|1赋值为j|0
dp[j][1][0] = dp[j][0][0];
dp[j][1][1] = dp[j][0][1];
}
dp[j][0][0] = dp[j-1][0][0];
dp[j][0][1] = dp[j-1][0][1];
} else if (dp[j-1][0][1]>=dp[j][1][1]) { // j-1|0 >= j|1
if (dp[j-1][0][0]!=dp[j][0][0]) { // j-1|0与j|0的颜色不相同,则j|1赋值为j-1|0
dp[j][1][0] = dp[j-1][0][0];
dp[j][1][1] = dp[j-1][0][1];
} else if (dp[j-1][1][1]>=dp[j][1][1]){ // 此时j-1|1与j|1颜色必不相同,若j-1|1值更大则赋值为j-1|1
dp[j][1][0] = dp[j-1][1][0];
dp[j][1][1] = dp[j-1][1][1];
}
}
}
if (dp[0][0][0]!=c) { // 前i-1个球都被选择,且第i和第i-1个球颜色不一样
dp[0][0][0] = c;
dp[0][0][1] += v;
} else // 前i-1个球都被选择,但第i和第i-1个球颜色相同
dp[0][0][1] = -inf;
// cout << dp[1][0][0] << ' ' << dp[1][0][1] << ' ' << dp[1][1][0] << ' ' << dp[1][1][1] << endl;
}
if (dp[k][0][1]<0)
cout << -1 << endl;
else
cout << dp[k][0][1] << endl;
}