[题解] P10561 [ICPC2024 Xi'an I] Smart Quality Inspector
发现
由于我们要求
设
设贡献到的区间数为
Code:
#include <bits/stdc++.h>
using namespace std;
int n, k, m, l, r, ans=1e9, pre[25][25], f[2000010], lst[25], nxt[25];
int main(){
scanf ("%d%d%d", &n, &k, &m);
for (int i=1; i<=m; i++){
scanf ("%d%d", &l, &r);
pre[l][r] ++;
}
for (int i=1; i<=n; i++){
for (int j=1; j<=n; j++){
pre[i][j] = pre[i][j] + pre[i][j-1] + pre[i-1][j] - pre[i-1][j-1];
}
}
for (int S=1; S<(1<<n); S++){
int tot = 0;
for (int i=0; i<n; i++){
if ((S >> i) & 1) tot ++;
}
if (tot > k) continue;
f[S] = 1e9, lst[0] = 0, nxt[n+1] = n+1;
for (int i=0; i<n; i++){
if ((S >> i) & 1) lst[i+1] = i+1;
else lst[i+1] = lst[i];
}
for (int i=n-1; i>=0; i--){
if ((S >> i) & 1) nxt[i+1] = i+1;
else nxt[i+1] = nxt[i+2];
}
for (int i=0; i<n; i++){
if (!((S >> i) & 1)) continue;
int T = S - (1 << i);
int st = lst[i], ed = nxt[i+2] - 2;
int ad = pre[i+1][ed+1] - pre[st][ed+1] - pre[i+1][i] + pre[st][i];
f[S] = min(f[S], f[T] + ad * (k - tot + 1));
}
if (tot == k) ans = min(ans, f[S]);
}
printf ("%d\n", ans);
return 0;
}