题目链接: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 }