cf1497 D. Genius
题意:
有 \(n\) 道题,每道题有难度 \(c_i=2^i\),标签 \(tag_i\) 和分数 \(s_i\)。初始智商 \(IQ=0\),做完第 \(i\) 题后,若 \(IQ<|c_i-c_j| \and tag_i \neq tag_j\) 则下一道可以做第 \(j\) 题,同时更新 \(IQ=|c_i-c_j|\) 然后得到 \(|s_i-s_j|\) 的分数
问最多能得多少分
\(n\le 5000\)
思路:
题意花里胡哨的。实际上只需注意到:
若序号小于 \(i\) 的题只在 \(1\sim i-1\) 内互相转移,则下一道一定可以做 \(i\),即 \(f_i=\max\limits_{j<i\and tag_i \neq tag_j} \{f_j + |s_i-s_j| \}\)
还有一种路径 \(k\to j\to i\),其中 \(k<j<i\)
void sol() {
int n; cin >> n;
vector<int> tag(n); for(int &x : tag) cin >> x;
vector<int> s(n); for(int &x : s) cin >> x;
vector<long long> f(n, 0);
for(int i = 0; i < n; i++)
for(int j = i-1; j >= 0; j--) if(tag[i] != tag[j]) {
long long fi = f[i]; //临时副本
f[i] = max(f[i], f[j] + abs(s[i]-s[j])),
f[j] = max(f[j], fi + abs(s[i]-s[j]));
}
cout << *max_element(f.begin(), f.end()) << '\n';
}

浙公网安备 33010602011771号