Codeforces1221 D. Make The Fence Great Again(DP)

在这里插入图片描述

题意:

给定一串数字,现在你要把这串数字变为相邻数字不相等的一串数字,变化方法为:对某个位置的数+1(可加无限多次),且有一定的花费,每个位置花费不同,问最小花费。

我们很清晰的知道每个数字最多只能加两次,为什么呢?因为加入 a i a_i a i + 1 a_{i + 1} 相等,加入这次我们改变 a i a_i ,那么 a i + = 1 a_i += 1 ;加了之后如果形成了 a i 1 = = a i a_{i - 1} == a_i ,那么我们还可以选择其中较小的花费加 1 1 ,也就是有可能选择 a i a_i 又加一,此时 a i a_i 肯定和两端的数字都不一样。所以说每个数字必定最多加两次就可以使得他和左右两边的数字都不一样。我们用 d p i j dp_{ij} 表示第i个数字加了 j j 次使得第 i i 个数字之前的所有数字不矛盾的最小花费,用 j j 表示第 i 1 i-1 个数加的次数, k k 表示第 i i 个数加的次数。

AC代码:

const int N = 3e5 + 10;
int n, m, t;
int c, x;
ll a[N], b[N];
ll dp[N][3];
 
ll min(ll a, ll b)
{
	return a > b ? b : a;
}
 
int main()
{
	sd(t);
	while (t--)
	{
		sd(n);
		rep(i, 0, n)
		{
			rep(j, 0, 2)
				dp[i][j] = INF;
		}
		rep(i, 1, n)
		{
			sldd(a[i], b[i]);
		}
		dp[0][0] = 0;
		rep(i, 1, n)
		{
			rep(j, 0, 2)
			{
				rep(k, 0, 2)
				{
					if (a[i] + j != a[i - 1] + k)
						dp[i][j] = min(dp[i][j], dp[i - 1][k] + j * b[i]);
				}
			}
		}
		pld(min(min(dp[n][0], dp[n][1]), dp[n][2]));
	}
	return 0;
}
发布了786 篇原创文章 · 获赞 460 · 访问量 24万+

猜你喜欢

转载自blog.csdn.net/qq_43627087/article/details/105237652