P9408 『STA - R2』Locked 题解

P9408

容易想到枚举最大值,令 fi,j 表示前 i 个数变为不降序列且第 i 个数为 j 的最小操作次数。

先考虑暴力转移:fi,j=fi1,k+chg(ai,j),其中 chg(i,j) 表示 ij 的最少操作次数。这样是 O(nV2) 的,但能过,应该是因为有一个 12 的常数。

考虑优化。

发现 chg(ai,j) 是不变的,处理出 lstj 表示第 i1 个小于等于 j 时,操作的最少次数,这样就可以 O(1) 转移了。

不升序列同理。

时间复杂度:O(nV)

代码:

const int N = 5e6 + 10;
int n;
int a[N], lst[10];
int f[N][10], g[N][10];

int chg(int x, int y) {
	if (x < y) swap(x, y);
	return min(x - y, y + 10 - x);
}

int main() {
	ios
	cin >> n;
	for (int i = 1; i <= n; i++) cin >> a[i];
	memset(f, 0x3f, sizeof(f)), memset(g, 0x3f, sizeof(g));
	for (int i = 0; i <= 9; i++)
		f[1][i] = chg(i, a[1]);
	for (int i = 0; i <= 9; i++)
		g[n][i] = chg(i, a[n]);
	for (int i = 2; i <= n; i++) {
		lst[0] = f[i - 1][0];
		for (int j = 1; j <= 9; j++) lst[j] = min(lst[j - 1], f[i - 1][j]);
		for (int j = 0; j <= 9; j++)
			f[i][j] = lst[j] + chg(a[i], j);
	}
	for (int i = n - 1; i >= 1; i--) {
		lst[0] = g[i + 1][0];
		for (int j = 1; j <= 9; j++) lst[j] = min(lst[j - 1], g[i + 1][j]);
		for (int j = 0; j <= 9; j++)
			g[i][j] = lst[j] + chg(a[i], j);
	}
	int ans = inf;
	for (int i = 1; i <= n; i++)
		for (int j = 0; j <= 9; j++)
			ans = min(ans, f[i][j] + g[i][j] - chg(j, a[i]));
	cout << ans << "\n";
	return 0;
}
posted @   Pengzt  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示