题目链接:https://codeforces.ml/problemset/problem/1437/C
题意:T组样例
每组一个n,然后大小为n的数组a(1<=ai<=n)。然后要求取n个不一样的数bi且>0,然后计算sum(abs(ai-bi))的最小值。
题解:一道dp背包题
dp[i][j]代表第i时刻取走前j道菜,这时候就分俩种情况取或者不取,取的话dp[i][j] = dp[i-1][j-1] + abs(t[i] - i), 不取的话 dp[i][j] = d[i-1][j],则dp[i][j] = min(dp[i-1][j], dp[i-1][j-1] + abs(t[i] - i));
注意:
- i的取值范围,因为t[i] < n, 所以i的最大值是2*n
- j的取值范围,1-n
- 初始化,dp[i][j] = 0x3f3f3f, dp[i][0] = 0;
1 #include<bits/stdc++.h>
2 using namespace std;
3 #define ll long long
4 const int N = 405;
5 const int INF = 0x3f3f3f;
6 int dp[N][N];
7 int t[N];
8 int main() {
9 int T;
10 cin >> T;
11 while (T--) {
12 int n;
13 cin >> n;
14 memset(t, 0, sizeof(t));
15 for (int i = 0; i < N; i++) {
16 for (int j = 0; j < N; j++) {
17 dp[i][j] = INF;
18 }
19 }
20 for (int i = 0; i <= 2*n; i++) dp[i][0] = 0;
21 for (int i = 1; i <= n; i++) cin >> t[i];
22 sort(t+1, t+n+1);
23 for (int i = 1; i <= 2*n; i++) {
24 for (int j = 1; j <= n; j++) {
25 dp[i][j] = min(dp[i-1][j], dp[i-1][j-1] + abs(t[j] - i));
26 }
27 }
28 cout << dp[2*n][n] << "
";
29 }
30 return 0;
31 }