LuoguP7714 「EZEC-10」排列排序 题解
Content
给定一个 \(1\sim n\) 的一个排列 \(p\),你每次可以选择一个区间 \([l,r]\) 并花费 \(r-l+1\) 的代价将下标在这个区间内的所有数升序排序,求使得排列 \(p\) 从 \(1\sim n\) 按升序排序的最少代价。
数据范围:\(t\) 组数据,\(1\leqslant t,\sum n\leqslant 10^6\)。
Solution
我们直接来考虑正解。
我们不妨考虑怎样去选择区间才能做到最小代价,然后我们不难想到这样的贪心做法:如果一段区间 \([l,r]\) 里面的所有数是一个 \(l\sim r\) 的一种排列并且区间长度不为 \(1\)(长度为 \(1\) 的话不需要花费 \(1\) 的代价去升序排列这个区间),那么我们就立即选择这一个区间翻转,并更新下一个需要翻转的区间的左端点。这样可以保证花费的代价是最小的。
具体如何判断一段区间 \([l,r]\) 里面的所有数是一个 \(l\sim r\) 的一种排列,我们只需要边输入的时候边判断前缀区间 \([1,i]\) 中的数的最大值是否就是 \(i\) 即可,详情请看代码。
Code
int p[1000007];
int main() {
MT {
int n = Rint, maxi = 0, ans = 0, l = 1;
F(int, i, 1, n) {
p[i] = Rint, maxi = max(maxi, p[i]);
if(maxi == i) ans += (i - l + 1 != 1) * (i - l + 1), l = i + 1; //这里将 (i - l + 1 != 1) 当做一个 0/1 值,可以省略掉一个 if
}
println(ans1);
}
return 0;
}

浙公网安备 33010602011771号