【四边形不等式】POJ1160[IOI2000]-Post Office
2024-08-25 10:28:39
【题目大意】
v个村庄p个邮局,邮局在村庄里,给出村庄的位置,求每个村庄到最近邮局距离之和的最小值。
【思路】
四边形不等式,虽然我并不会证明:(
dp[i][j]表示前i个村庄建j个邮局的最小值,w[i][j]表示在i到j之间建立一个邮局的最小值。w[i][j]显然取i~j的中位数,可以在O(1)时间内求出。
显然dp[i][j]=min{dp[k][j-1]+w[k+1][i]}。
傻傻写错i和j……
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int MAXV=;
const int MAXP=;
const int INF=0x7fffffff;
int v,p;
int dis[MAXV],sum[MAXV],w[MAXV][MAXV];//w[i][j]表示在[i,j]间建立一个邮局的最小代价
int s[MAXV][MAXP],dp[MAXV][MAXP]; void init()
{
scanf("%d%d",&v,&p);
sum[]=;
for (int i=;i<=v;i++) scanf("%d",&dis[i]);
sort(dis+,dis+v+);
for (int i=;i<=v;i++) sum[i]=dis[i]+sum[i-];
for (int i=;i<=v;i++)
{
w[i][i]=;
for (int j=i+;j<=v;j++)
{
if ((i+j)%==) w[i][j]=sum[j]-sum[(i+j)/]-sum[(i+j)/-]+sum[i-];
else w[i][j]=sum[j]-sum[(i+j)/]-sum[(i+j)/-]+sum[i-]-dis[(i+j)/];
}
}
} void solve()
{
memset(dp,,sizeof(dp));
for (int i=;i<=v;i++) dp[i][]=w[][i];
for (int j=;j<=p;j++)
{
s[v+][j]=v-;
for (int i=v;i>=j;i--)
{
for (int k=s[i][j-];k<=s[i+][j];k++)
{
if (dp[i][j]>dp[k][j-]+w[k+][i])//一开始这里敲成了w[k+1][j]
{
dp[i][j]=dp[k][j-]+w[k+][i];
s[i][j]=k;
}
}
}
}
printf("%d",dp[v][p]);
} int main()
{
init();
solve();
return ;
}
最新文章
- ACM: Gym 101047E Escape from Ayutthaya - BFS
- Lua Coroutine详解
- Redis中统计各种数据大小的方法
- C# 匿名函数 详解
- Hibernate框架概念
- ubuntu + hadoop2.5.2分布式环境配置
- 《Java数据结构与算法》笔记-CH5-链表-4用链表实现堆栈
- rand5()产生rand7()
- iOS8中添加的extensions总结(一)——今日扩展
- IIS启用GZip压缩
- phpstorm php $post数据为空的原因
- 【Python3之内置函数】
- 举例MyBatis的常用的API及方法
- 【NOIP2016TG】solution
- [Swift]LeetCode144. 二叉树的前序遍历 | Binary Tree Preorder Traversal
- Unity资源 ----加载最好需要做哪些事
- Springfox与swagger的整合使用
- 2.04-proxy-handler
- C盘满了如何清理
- IIS 6 备忘