0%

Educational Codeforces Round 97 - C - Chef Monocarp

题目

https://codeforces.com/contest/1437/problem/C

思路

dp,先对$a_i$升序排序,设$dp(i,j)$,$i$为前$a_i$的情况,$j$为选择减去的数字。初始化$dp(i,0)$为$\infty$(因为不能取0),状态转移方程$dp(i,j)\leftarrow\max(dp(i,j-1),dp(i-1,j-1)+abs(a_i-j))$。
注意$j$可能的取值,考虑$n,t$最大为200,则$j$最大取值为$200+199=399$,这里取405。

AC代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
struct _IO { _IO() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); } }_io;
typedef long long ll; typedef long double ld; typedef pair<ll, ll> pll;

ll n, a[205], dp[205][405];

int main()
{
ll T;
cin >> T;
while (T--)
{
cin >> n;
for (ll i = 0; i < n; ++i) cin >> a[i];
sort(a, a + n);
for (ll i = 0; i < n; ++i) dp[i][0] = 1e12;

for (ll i = 1; i < 405; ++i)
dp[0][i] = min(dp[0][i - 1], abs(a[0] - i));

for (ll i = 1; i < n; ++i)
{
for (ll j = 1; j < 405; ++j)
{
dp[i][j] = min(dp[i][j - 1], dp[i - 1][j - 1] + abs(a[i] - j));
}
}

cout << dp[n - 1][405 - 1] << endl;
}
return 0;
}