Meaning...
First, sort the order from small to large, and obtain it after analysis. If you want to go to the I, then the I-1 item also need to take (because it is out of order and I difference is the smallest I-1 or I + 1, But I + 1 and I can also be seen as I and I-1, so if you want to go to the I, then the I-1 item also needs to take ).
Analysis: Set DP [I] [J] to indicate that there are I items, and use j pairs. The I-th item has two conditions for DP [I] [J:
1: If you do not want to take the I item, then the DP [I] [J] = DP [I-1] [J] (think carefully)
II. If you want to obtain the I-th item, then there is DP [I] [J] = DP [I-2] [J-1] + pow2 (s [I]-s [I-1]) (because if you want to go to the I, then the I-1 item also want to take, so is the I-2, And because take a pair, so is the J-1 );
Note 1: because the minimum fatigue value is to be found, the minimum values of the above two cases are taken.
NOTE 2: during initialization, DP [I] [0] = 0. Other values are initialized to a large number.
Code:
#include <cstdio>#include <cstring>#include <algorithm>#define M 2050#define INF 0x7f7f7f7fusing namespace std;int s[M];int dp[M][M];int pow2(int x){return x*x;}void solve(int n, int m){int i, j;for(i = 1; i <= n; i ++){for(j = 1; j <= n/2; j ++){dp[i][j] = INF;}dp[i][0] = 0;}for(i = 2; i <= n; i ++){for(j = 1; j <= i/2; j ++){dp[i][j] = min(dp[i-1][j], dp[i-2][j-1]+pow2(s[i]-s[i-1]));}}printf("%d\n", dp[n][m]);}int main(){int n, m, i;while(scanf("%d%d", &n, &m) == 2){for(i = 1; i <= n; i ++){scanf("%d", &s[i]);}sort(s+1, s+n+1);solve(n, m);}return 0;}
Question link: http://acm.hdu.edu.cn/showproblem.php? PID = 1, 1421
Hdoj 1421 move dormitory [DP]