死了吗小枫~ 死了吗小枫~ |

GCSG01

园龄:1年3个月粉丝:2关注:20

CF571B-题解

CF571B

题意

给定数组A 和值k ,你可以重排A 中的元素,使得i=1nk|AiAi+k| 最小。输出最小值。

思路

Ai,Ai+k 就等同于在将 ik 的意义上把 A 分为若干组
贪心的想要使 i=1nk|AiAi+k| 最小就等同于让每组内的数字差异尽可能小,所以将原数组进行排序。
dpi,j 为选上述第一种组别 i 次,选第二种组别 j 次的最小值,对于每个组数字,结果为末项减首项,得到转移方程

dp[i][j]=min(dp[i-1][j]+a[now]-a[now-len]);
dp[i][j]=min(dp[i][j-1]+a[now]-a[now-len+1]);

Code

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=3e5+5;
int a[N];
int dp[5003][5003];
int n,k,ans;
signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    memset(dp,0x3f,sizeof(dp));
    cin>>n>>k;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    sort(a+1,a+n+1);
    int len=n/k,tot1=n%k,tot2;
    tot2=(n-tot1)/len-tot1;
    dp[0][0]=0;
    for(int i=0;i<=tot1;i++)
        for(int j=0;j<=tot2;j++)
        {
            int k=len*(i+j)+i;
            if(i)dp[i][j]=min(dp[i][j],dp[i-1][j]+a[k]-a[k-len]);
            if(j)dp[i][j]=min(dp[i][j],dp[i][j-1]+a[k]-a[k-len+1]);
            // cout<<k<<" "<<dp[i][j-1]+a[k]-a[k-len+1]<<" "<<dp[i-1][j]+a[k]-a[k-len]<<"\n";
        }
    cout<<dp[tot1][tot2];
    return 0;
}
posted @   GCSG01  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗
漂浮磁力线/鼠标吸铁石特效
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起