[IOI2000] 邮局
题目描述
高速公路旁边有一些村庄。高速公路表示为整数轴,每个村庄的位置用单个整数坐标标识。没有两个在同样地方的村庄。两个位置之间的距离是其整数坐标差的绝对值。
邮局将建在一些,但不一定是所有的村庄中。为了建立邮局,应选择他们建造的位置,使每个村庄与其最近的邮局之间的距离总和最小。
你要编写一个程序,已知村庄的位置和邮局的数量,计算每个村庄和最近的邮局之间所有距离的最小可能的总和。
对于
对于
思路点拨
我们从40分做起,这很好像,是子序列提取的模型,我们很容易设出状态并且转移。我们令
其中
走向左边的基站,其余走向右边的基站
这样有超时的风险。我们发现,对于同一个
n=read(),m=read();
for(int i=1;i<=n;i++) a[i]=read();
for(int i=1;i<=n;i++) sum[i]=sum[i-1]+a[i];
sort(a+1,a+n+1);
for(int l=2;l<n;l++){
int id=l;
for(int r=l;r<n;r++){
while(a[id]-a[l-1]<=a[r+1]-a[id]) id++;
//id肯定会到右边去
w[l][r]=(sum[id-1]-sum[l-1])-(id-l)*a[l-1]+(r-id+1)*a[r+1]-(sum[r]-sum[id-1]);
}
}
我们接下来就不好优化了。但是这个dp是二维的,求得是最小值,我们不妨对
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=-f;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
const int MAXN=3e3+10;
int n,m,a[MAXN],sum[MAXN];
int w[MAXN][MAXN];
int pos[MAXN][MAXN],f[MAXN][MAXN];
signed main(){
n=read(),m=read();
for(int i=1;i<=n;i++) a[i]=read();
for(int i=1;i<=n;i++) sum[i]=sum[i-1]+a[i];
sort(a+1,a+n+1);
for(int l=2;l<n;l++){
int id=l;
for(int r=l;r<n;r++){
while(a[id]-a[l-1]<=a[r+1]-a[id]) id++;
//id肯定会到右边去
w[l][r]=(sum[id-1]-sum[l-1])-(id-l)*a[l-1]+(r-id+1)*a[r+1]-(sum[r]-sum[id-1]);
}
}
for(int l=1;l<=n;l++)
w[l+1][l]=0;
for(int i=0;i<MAXN;i++)
for(int j=0;j<MAXN;j++)
f[i][j]=1e9;
for(int i=1;i<=n;i++){
f[i][1]=a[i]*(i-1)-sum[i-1];
pos[i][1]=1;
}
for(int j=2;j<=m;j++){
f[j][j]=0;
pos[j][j]=j;
pos[n+1][j]=n;
for(int i=n;i>j;i--){
for(int k=pos[i][j-1];k<=pos[i+1][j];k++)
if(f[i][j]>f[k][j-1]+w[k+1][i-1]){
f[i][j]=f[k][j-1]+w[k+1][i-1];
pos[i][j]=k;
}
}
}
int ans=1e9;
for(int i=m;i<=n;i++)
ans=min(ans,f[i][m]+sum[n]-sum[i]-(n-i)*a[i]);
cout<<ans;
return 0;
}
分类:
动态规划
, 动态规划 / 四边形不等式优化动态规划
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现