CF571B Minimization

https://www.luogu.com.cn/problem/CF571B

还是有点厉害的 *2000。

考虑从 1 想起,那是不是 1+k,1+2k,1+3k...,那么发现可以按 modk 分组,然后你会发现这些组的长度仅有 nknk+1,又考虑一定是选择排序后连续的一段,因为这样子就是 maxmin,其他情况都不更优(这也是典),那么 dp 即可。

#include <bits/stdc++.h> #define int long long #define pb push_back using namespace std; const int N=(int)(3e5+5); int n,k,a[N],cnt[N],f[5005][5005]; signed main() { cin.tie(0); ios::sync_with_stdio(false); // cout<<"qwq"; cin>>n>>k; for(int i=1;i<=n;i++) cin>>a[i]; sort(a+1,a+1+n); for(int i=1;i<=n;i++) { ++cnt[(i-1)%k]; } int res1=0,res2=0,len1=n/k,len2=n/k+1; for(int i=0;i<k;i++) { if(cnt[i]==len1) ++res1; else if(cnt[i]==len2) ++res2; // cout<<cnt[i]<<'\n'; } // cout<<res1<<" "<<res2<<'\n'; memset(f,0x3f,sizeof(f)); f[0][0]=0; for(int i=0;i<=res1;i++) { for(int j=0;j<=res2;j++) { if(!i&&!j) continue ; int p=i*len1+j*len2; if(i>=1&&p>=len1) f[i][j]=min(f[i][j],f[i-1][j]+a[p]-a[p-len1+1]); if(j>=1&&p>=len2) f[i][j]=min(f[i][j],f[i][j-1]+a[p]-a[p-len2+1]); } } cout<<f[res1][res2]; return 0; }

__EOF__

本文作者F x o r G
本文链接https://www.cnblogs.com/xugangfan/p/16479467.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   FxorG  阅读(25)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示