1. 题目描述
给定⼀个⻓为
n
n
n 的序列 A
,其中序列中的元素都是 0 ~ 9
之间的整数,对于⼀个⻓度同样为
n
n
n 整数序列B
,定义其权值为
∣
A
[
i
]
−
B
[
i
]
∣
(
1
≤
i
≤
n
)
| A[i] - B[i] | (1 \leq i \leq n)
∣A[i]−B[i]∣(1≤i≤n) 之和加上
(
B
[
j
]
−
B
[
j
+
1
]
)
2
(
1
≤
j
≤
n
)
( B[j] - B[j+1])^2 (1 \leq j \leq n)
(B[j]−B[j+1])2(1≤j≤n) 之和。求所有⻓为 n
的整数序列中,权值最⼩的序列的权值是多少。
输入示例
6
1 4 2 8 5 7
输出示例
11
2. 我的尝试
这是一道动态规划题目。
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10, INF = 0x3f3f3f3f;
// f[i][j]表示前i个数字(也就是1到i),且b[i] == j 的权值和最小值,其中j小于10
int n;
int f[N][10];
int nums[N];
// 计算绝对值
int abs(int x, int y) {
return x > y ? x - y : y - x;
}
int main() {
cin >> n;
for (int i = 1; i <= n; i ++) scanf("%d", &nums[i]);
for (int i = 1; i <= n; i++)
for (int j = 0; j < 10; j++)
f[i][j] = INF;
// 转移方程:f[i][j]可由 前i-1个数字,且b[i - 1] == k 的权值和最小值f[i - 1][k]
// 加上a[i]这一位的权值,最后取min
for (int i = 1; i <= n; i ++)
for (int j = 0; j < 10; j++)
for (int k = 0; k < 10; k++)
f[i][j] = min(f[i - 1][k] + abs(j, nums[i]) + (j - k) * (j - k), f[i][j]);
int res = INF;
for (int i = 0; i < 10; i++)
res = min(f[n][i], res);
cout << res;
return 0;
}