50分做法:n方dp
考虑\(f[i][j]\)为前i个数,第j个数是i之前与i染色不同的数,则考虑i+1染色与哪个数相同,可转移到\(f[i+1][i], f[i+1][j]\)
65做法:优化到n*值域
100分做法:继续优化式子达到线性
还有人类智慧做法,但是能优化就不需要智慧
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e6+10;
int n, a[N], c[N], f[N], mx, tag;
bool vis[20];
void solve(){mx = tag = 0;cin >> n;for (int i = 1; i <= n; i++) cin >> a[i];int ans = 0;for (int i = 0; i <= N/2; i++) c[i] = -0x3f3f3f3f3f3f3f3f;c[0]=0;for (int i = 2; i <= n; i++) {int x=0;if (a[i] == a[i-1]) tag += a[i],x=a[i];c[a[i-1]] = max(mx-x, c[a[i-1]]);c[a[i-1]] = max(c[a[i-1]], c[a[i]]+a[i]-x);mx = max(mx, c[a[i-1]]);// for(int j=1;j<=5;j++)cout<<c[j]<<' ';// cout<<endl;}cout << mx + tag << endl;
}
// void solve() {
// cin >> n;
// for (int i = 1; i <= n; i++) cin >> a[i], lst[i] = c[a[i]], c[a[i]] = i;
// for (int i = 1; i <= n; i++) {
// pre[i] = pre[i-1] + ((a[i] == a[i-1]) ? a[i] : 0);
// }
// for (int i = 1; i <= n; i++) {
// f[i] = max(f[i], f[i-1]); lan[i] = lan[i-1];
// if(lst[i] < i-1) {
// int t = f[lst[i]] + a[i] + pre[i-1] - pre[lst[i] + 1] + (a[lan[lst[i]]] == a[lst[i]+1]) ? a[lst[i]+1] : 0;
// if (f[i] < t) f[i] = t, lan[i] = i-1;
// }
// }
// cout<<f[n]<<endl;
// for(int i = 1; i <= n; i++) f[i] = lst[i] = pre[i] = 0;
// for(int i = 1; i <= N/2; i++) c[i] = 0;
// }
signed main(){int T;cin >> T;while(T--) solve();
}