CF2129 Div1
发现最优的情况 \(S\),应满足 \(g(S)=0\),所以答案为 \(f(S)\)。
考虑什么时候 \(g(S)=0\),显然当没有环时 \(g(S)=0\),这等价于所选的线段中没有一条是另一条的子集。
#include <bits/stdc++.h>
using namespace std;
const int kN = 3e3 + 7;
int n, a[kN], b[kN], vis[kN];
void solve(){
cin >> n;
for(int i = 1; i <= n; i++) cin >> a[i] >> b[i], vis[i] = 0;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++){
if(i != j && a[j] <= a[i] && b[i] <= b[j]){
vis[i] = 1; break;
}
}
}
vector<int> ans;
for(int i = 1; i <= n; i++){
if(!vis[i]) ans.push_back(i);
}
cout << ans.size() << '\n';
for(int i : ans) cout << i << ' ';
cout << '\n';
}
signed main(){
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int T = 1; cin >> T;
while(T--) solve();
return 0;
}
注意到有 \(p_i \le p_j \le 2 \times n-p_j \le 2 \times n - p_i\),所以对于 \(a_i\) 来说,\(a_i\) 取 \(p_i\) 或 \(2 \times n - p_i\) 时与其他 \(a_i\) 的取值的相对大小关系都是固定的。所以我们考虑从小到大枚举 \(p_i\),若 \(a_i=p_i\),则答案贡献为前 \(i\) 个数中比 \(p_i\) 大的数 \(p_j\),否则为后面比 \(i\) 大的数 \(p_j\)。每次删除最小值即可。
#include <bits/stdc++.h>
using namespace std;
const int kN = 5e3 + 7;
int n, p[kN], a[kN], vis[kN], ans;
void solve(){
cin >> n; ans = 0;
for(int i = 1; i <= n; i++) cin >> p[i], a[p[i]] = i, vis[i] = 1;
for(int i = 1; i <= n; i++){
int x = a[i], l = 0, r = 0;
for(int i = 1; i < x; i++) if(vis[i]) ++l;
for(int i = x + 1; i <= n; i++) if(vis[i]) ++r;
ans += min(l, r);
vis[x] = 0;
}
cout << ans << '\n';
}
signed main(){
int T = 1; cin >> T;
while(T--) solve();
return 0;
}

浙公网安备 33010602011771号