2020牛客寒假算法基础集训营2 H施魔法 dp详解

本文通过动态规划(DP)解决了一个关于寻找数组中k个数的最小极值差的问题。介绍了问题的背景,详细阐述了DP算法的实现思路,并提供了完整的C++代码示例。关键在于状态转移方程的推导,以及如何通过排序和DP计算得到最优解。
摘要由CSDN通过智能技术生成

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值