csp2024T3染色

lyrrr發表於2024-11-30

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();
}

相關文章