【题解】P3049

Link

考试的 B 题。

不难想到 DP。(然鹅我没想到 qwq)

我们先将数组进行一个神奇的处理,以样例为例:

\(a={1,2,3,4}\to a'={1,2,2,3,3,3,4,4,4,4}\)

\(b={4,3,2,0}\to b'={1,1,1,1,2,2,2,3,3}\)

这时就变成了我们熟悉的“编辑字符距离”的问题。P2758 编辑距离

状态转移方程:

dp[i][j] = min(min(dp[i][j - 1] + x, dp[i - 1][j] + y), dp[i - 1][j - 1] + z * abs(a[i] - b[j]))

记得设边界条件。

\(\text{Code}\)

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;

const int MAXN = 1e3 + 5;

int n, x, y, z, lena, lenb;
int a[MAXN], b[MAXN], dp[MAXN][MAXN];

int main()
{
	scanf("%d%d%d%d", &n, &x, &y, &z);
	for (int i = 1; i <= n; i++)
	{
		int c, d;
		scanf("%d%d", &c, &d);
		for (int j = 1; j <= c; j++) //预处理
		{
			a[++lena] = i;
		}
		for (int j = 1; j <= d; j++)
		{
			b[++lenb] = i;
		}
	}
	for (int i = 1; i <= lena; i++) //边界条件
	{
		dp[i][0] = y * i;
	}
	for (int i = 1; i <= lenb; i++)
	{
		dp[0][i] = x * i;
	}
	for (int i = 1; i <= lena; i++)
	{
		for (int j = 1; j <= lenb; j++)
		{
			dp[i][j] = min(min(dp[i][j - 1] + x, dp[i - 1][j] + y), dp[i - 1][j - 1] + z * abs(a[i] - b[j]));
		}
	}
	printf("%d", dp[lena][lenb]);
	return 0;
}
posted @ 2021-08-07 18:01  mango09  阅读(33)  评论(0编辑  收藏  举报
-->