P4767 [IOI2000] 邮局 加强版
P4767 [IOI2000] 邮局 加强版
双倍经验P10967 [IOI2000] 邮局(原始版)
题目翻译:
给定村庄数量
思路:
法一: 我们可以很快看出一个关系,令
若直接枚举所有的
法二: 我们考虑优化,可以发现
因此其转移可以优化到
法三: 继续考虑优化,我们可以发现
考虑转换,令
j=j+1 w[i][j+1]-w[i][j]=x[i]-x[\lfloor \frac{i+j+1}{2}\rfloor] 令
i=i+1,j=j+1 ,则有w[i+1][j+1]-w[i+1][j]=x[i+1]-x[\lfloor \frac{i+j+2}{2}\rfloor] 联立两式,使一式减二式:
w[i][j+1]-w[i][j]-(w[i+1][j+1]-w[i+1][j])=x[i]-x[\lfloor \frac{i+j+1}{2}\rfloor]-(x[i+1]-x[\lfloor \frac{i+j+2}{2}\rfloor]) 化简可得:
x[\lfloor \frac{i+j+2}{2}\rfloor]-x[\lfloor \frac{i+j+1}{2}\rfloor]=0 由于
x 的坐标单调递增,则有:x[\lfloor \frac{i+j+2}{2}\rfloor]-x[\lfloor \frac{i+j+1}{2}\rfloor] \geq 0 及
w[i+1][j]-w[i+1][j+1]-(w[i][j]-w[i][j+1]) \le 0 转换位置得:
w[i+1][j]+w[i][j+1] \le w[i][j]+w[i+1][j+1] 则
\forall {a \le b \le c \le d} ,满足w[a][d] \geq w[b][c] 可知w[i][j] 满足四边形不等式,则dp[i][j] 也满足四边形不等式
由次可知,对于
我们只需要在转移时在区间
完整代码:
#include<bits/stdc++.h>
using namespace std;
const int N=3010;
int x[N],dp[N][N],w[N][N],d[N][N];
int main(){
int v,p;
cin>>v>>p;
for(int i=1;i<=v;i++)cin>>x[i];
for(int i=1;i<=v;i++){
w[i][i]=0;
for(int j=i+1;j<=v;j++){
w[i][j]=w[i][j-1]+x[j]-x[(i+j)>>1];
}
}
sort(x+1,x+v+1);
memset(dp,0x3f,sizeof(dp));
dp[0][0]=0;
for(int j=1;j<=p;j++){
d[v+1][j]=v;
for(int i=v;i>=1;i--){
int mn=INT_MAX,minn;
for(int k=d[i][j-1];k<=d[i+1][j];k++){
if(dp[k][j-1]+w[k+1][i]<mn){
mn=dp[k][j-1]+w[k+1][i];
minn=k;
}
}
dp[i][j]=mn;
d[i][j]=minn;
}
}
cout<<dp[v][p]<<endl;
}