题解:P11922 [PA 2025] 叠积木 / Wieża
Error_Eric · · 题解
Statement
每个积木块有边长和颜色。每个积木的价值是其边长。每一处相邻的积木,若颜色不同,则有
Sol
想要边长严格单调只需要 sort 之后将边长相同的一起转移即可。考虑怎么 dp。
记
如果不用考虑颜色,那就只需要维护所有
但是要考虑颜色,那么就对于每个颜色维护一下颜色
那么只有两个位置可能转移给
Code
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
using namespace std;
const int _= 5.1e5;
int n, c, a[_], col[_], g[_], h[3];
long long f[_];
#define B g[col[i]] // best option with ending of color of i so far
map<int, vector<int>> i_ata;
signed main(){
ios::sync_with_stdio(0),
cin.tie(0), cout.tie(0);
cin >> n >> c;
for(int i = 1; i <= n; i++)
cin >> a[i] >> col[i], i_ata[a[i]].push_back(i);
for(auto aval_ixs:i_ata){
auto aval = aval_ixs.first;
auto ixs = aval_ixs.second;
for(int i:ixs)
f[i] = max(f[B], f[h[h[0] == B]] - c) + aval;
for(int i:ixs){
if(f[i] > f[B]) B = i;
if(f[i] > f[h[0]]){
if(col[h[0]] != col[i])
h[1] = h[0];
h[0] = i;
}
else if(f[i] > f[h[1]] && col[h[0]] != col[i])
h[1] = i;
}
}
cout << *max_element(f+1, f+n+1) << endl;
return 0;
}