CF1730F Almost Sorted (状压 dp)
状压 dp
题目的描述有点奇怪,实际上就是将
根据条件,我们猜测前面的数都不会很大,于是考虑从左到右插入值,若当前插入的值为
考虑 dp。
转移考虑枚举下一个要放的数,并处理出对应增加的逆序对数,
复杂度
PS:可以用 BIT 将
#include <bits/stdc++.h>
#define pii std::pair<int, int>
#define fi first
#define se second
#define pb push_back
using i64 = long long;
using ull = unsigned long long;
const i64 iinf = 0x3f3f3f3f, linf = 0x3f3f3f3f3f3f3f3f;
const int N = 5e3 + 10, K = 9;
int n, k, lim;
int pos[N], sum[N];
int f[N][1 << K];
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cin >> n >> k;
k++;
for(int i = 1; i <= n; i++) {
int p;
std::cin >> p;
pos[p] = i;
}
lim = (1 << k) - 1;
memset(f, 0x3f, sizeof(f));
f[0][0] = 0;
for(int i = 0; i <= n; i++) {
if(i) {
for(int j = 1; j < pos[i]; j++) sum[j]++;
}
for(int s = 0; s <= lim; s++) {
if(f[i][s] == iinf) continue;
for(int j = 1; j <= k && i + j <= n; j++) {
if(!(s >> (j - 1) & 1)) {
int p = i, t = s | (1 << (j - 1)), val = sum[pos[i + j]];
while(t & 1) {
p++;
t >>= 1;
}
for(int x = 1; x <= k && i + x <= n; x++) if((s >> (x - 1) & 1) && pos[i + x] > pos[i + j]) val++;
f[p][t] = std::min(f[p][t], f[i][s] + val);
}
}
}
}
std::cout << f[n][0] << "\n";
return 0;
}
标签:
DP
Buy me a cup of coffee ☕.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!