题目描述
输入格式
输出格式
样例
数据范围与提示
对于 100%100\%100% 的数据,1≤n≤106,1≤k≤106,1≤vi≤1091leq nleq 10^6,1leq kleq 10^6,1leq v_ileq 10^91≤n≤10
6,1≤k≤106,1≤vi≤109。
题意 :类似于“拉火车”游戏,不过不太一样的是当出现相同的情况后你可以选择拉或者不拉,
思路分析 : 一看就是个 dp ,
dp[i] = dp[i-1]
dp[i] = max(dp[i], dp[j-1]+sum[i]-sum[j-1]) , i 与 j 为花色相同的地方
第一次写的时候就类似纯暴力的了,每次转移的时候从前面所有相同的地方转移,用 vector 存的,超时.... 后面发现 转移方程中的式子是可以优化的,每次找 dp[j-1]-sum[j-1]中最大的转移即可
代码示例 :
#define ll long long
const ll maxn = 1e6+5;
ll n, k;
ll c[maxn], v[maxn];
ll sum[maxn], dp[maxn];
ll color[maxn];
void solve() {
memset(color, 0x8f, sizeof(color));
for(ll i = 1; i <= n; i++){
dp[i] = dp[i-1];
dp[i] = max(dp[i], sum[i]+color[c[i]]);
color[c[i]] = max(color[c[i]], dp[i-1]-sum[i-1]);
}
printf("%lld
", dp[n]);
}
int main() {
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
cin >> n >> k;
for(ll i = 1; i <= n; i++) {
scanf("%lld", &c[i]);
}
for(ll i = 1; i <= n; i++) {
scanf("%lld", &v[i]);
sum[i] = sum[i-1]+v[i];
}
solve();
return 0;
}