HDU1421
原题链接https://vjudge.net/contest/350953#problem/F
运用动态规划来解题,由于相邻的数的差值肯定较小,所以我们应该先排序,dp[i][j]=min(dp[i-1][j],dp[i-2][j-1]+(a[i-1]-a[i])*(a[i-1]-a[i])),对于每个j比较出相邻两个数中应该选哪一个
附一组数据
input:
7 3
7 9 4 3 1 9 2
output:
2
具体情况可以删去下方代码注释来一点一点分析。
第一列将前n项没两项的差值的最小值计算出来,
第二列从第4位开始 3 4 位加上前两位的最小值;
第5位加上前三位的最小值,再与上一个比较出大小,就求出了前5位取4个数的最小值,以此类推,
第三列从第5项开始,前四项的取四项的最小值加上5 6位,以及前六位的最小值加上6 7 位再与前者进行比较,较小的数即为答案。
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <queue>
#include <stack>
using namespace std;
long long a[20005];
long long dp[2005][2005];
int main()
{
long long n, k;
while (~scanf("%lld %lld", &n, &k))
{
memset(a, 0, sizeof(a));
long long i, j;
for (i = 0; i < n; i++)
{
scanf("%lld", &a[i]);
}
for (i = 0; i < n; i++)
{
for (j = 0; j <= k; j++)
{
if (j == 0)
{
dp[i][j] = 0;
}
else
{
dp[i][j] = 1e9;//dp给一个初始值,如果要分析可以改为100;
}
}
}
sort(a, a + n);
for (i = 2; i <= n; i++)
{
for (j = 1; j <= k && j <= i; j++)
{
dp[i][j] = min(dp[i - 2][j - 1] + (a[i - 1] - a[i - 2]) * (a[i - 1] - a[i - 2]), dp[i - 1][j]);
// for (int iii = 0; iii < n; iii++)
// {
// cout << a[iii] << " ";
// }
// cout << endl;
// for (int ii = 0; ii <= n; ii++)
// {
// cout << a[ii] << " ";
// for (int jj = 0; jj <= k; jj++)
// {
// printf("%4lld", dp[ii][jj]);
// }
// cout << endl;
// }
// cout << "**************" << endl;
}
// cout << "换行" << endl;
}
printf("%lld\n", dp[n][k]);
}
return 0;
}