题目链接:https://ac.nowcoder.com/acm/contest/3003/H
没想到是dp,还是看了大神的博客才发现。。。还应该多多练习。
借鉴了下大神的思路。
思路:
先排序。。。
dp,dp[i]表示前i项的最优解
首先应该清楚,至少选择k个数,那么前k-1的dp[i]可以全设为inf, dp[i]从第k项开始。我们应该清楚最小的极值差的数目可能有k项或者大于k,所以我们对每一个dp[i],应该考虑两个步骤:
1.向后延伸。
dp[i-1]+q[i]-q[i-1]
2.与后面断开
dp[i-k]+q[i]-q[i+1-k]
dp[i-k]: 表示包括i项的前k项的前一项的最优解。
q[i]-q[i+1-k]:表示包括i项的前k项的最优解。
那么我们就可以得出状态转移方程:
dp[i]=min(dp[i-1]+q[i]-q[i-1],dp[i-k]+q[i]-q[i+1-k]);
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
const int maxn=3e5+5;
const int inf=0x3f3f3f;
int q[maxn];
int dp[maxn];
int main()
{
int n,k;
scanf("%d%d",&n,&k);
memset(dp,inf,sizeof(dp));
for(int i=1;i<=n;i++)
{
scanf("%d",&q[i]);
}
sort(q+1,q+1+n);
int ans=0;
dp[k]=q[k]-q[1];
for(int i=k+1;i<=n;i++)
{
dp[i]=min(dp[i-1]+q[i]-q[i-1],dp[i-k]+q[i]-q[i+1-k]);
}
printf("%d\n",dp[n]);
}