首页 > 其他分享 >邮局--dp经典问题

邮局--dp经典问题

时间:2023-05-31 19:04:34浏览次数:34  
标签:建立 -- 邮局 int 村庄 include dp 坐标


题目:http://poj.org/problem?id=1160


题意: 一些村庄被建立在一条笔直的高速公路边上,我们用一条坐标轴来描述这条高速公路,每一个村庄的坐标都是整数,没

有两个村庄坐标相同。两个村庄间的距离,定义为它们的坐标值差的绝对值。我们需要在一些村庄建立邮局——当然,并不是每

一个村庄都必须建立邮局,邮局必须被建立在村庄里,因此它的坐标和它所在的村庄坐标相同。每个村庄使用离它最近的那个

邮局,建立这些邮局的原则是:所有村庄到各自所使用的邮局的距离总和最小。
    

你的任务是编写一个程序,在给定了每个村庄坐标和将要建立的邮局数之后,按照上述原则,合理地选择这些邮局的位置。

求出的所有村庄到距离它最近的邮局的距离总和.


分析:给定一个序列,假设我们要建一个邮局,那么一定是在这个序列的中点,所以我们可以先预处理出序列区间[l,r]之间建立

一个邮局的最短距离和w[l][r],然后用dp[i][j]表示到i个村庄建立j个邮局的最短距离和,那么就有状态转移方程:


邮局--dp经典问题_i++



#include <iostream>
#include <string.h>
#include <stdio.h>

using namespace std;
const int INF = ~0U>>1;
const int N = 305;

int w[N][N];
int dp[N][35];
int a[N];
int n,m;

void Init(int a[],int n)
{
    memset(w,0,sizeof(w));
    for(int i=1;i<=n;i++)
        for(int j=i+1;j<=n;j++)
            w[i][j] = w[i][j-1] + a[j] - a[(i+j)>>1];
}

int Work()
{
    for(int i=1;i<=n;i++)
    {
        dp[i][i] = 0;
        dp[i][1] = w[1][i];
    }
    for(int j=2;j<=m;j++)
    {
        for(int i=j+1;i<=n;i++)
        {
            dp[i][j] = INF;
            for(int k=j-1;k<i;k++)
                dp[i][j] = min(dp[i][j],dp[k][j-1] + w[k+1][i]);
        }
    }
    return dp[n][m];
}

int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        Init(a,n);
        printf("%d\n",Work());
    }
    return 0;
}





标签:建立,--,邮局,int,村庄,include,dp,坐标
From: https://blog.51cto.com/u_16146153/6388988

相关文章

  • 棋子--状态压缩dp
    题目描述:在一个N*N的棋盘上放棋子,每一个棋子的上下左右都没有棋子,也就是不相邻,一共有多少种放法?(N<=8)sample_input013sample_output1263分析:首先,我们可以逐行来摆放这些棋子,这样我们会发现,每一行的摆放状态只和上一行有关,这样我们可以采用递推的方式来解决。假设f[i......
  • 深度理解链式前向星
    我们首先来看一下什么是前向星.前向星是一种特殊的边集数组,我们把边集数组中的每一条边按照起点从小到大排序,如果起点相同就按照终点从小到大排序,并记录下以某个点为起点的所有边在数组中的起始位置和存储长度,那么前向星就构造好了.用len[i]来记录所有以i为起点的边在数组中的......
  • 当鼠标滑过文本框自动选中输入框内容JS代码
    代码:<html><head><title>响应鼠标自动选中文本框内容</title></head><body><inputid="a"type="text"value="请输入搜索词"οnmοuseοver="selectInputContent(this.id)"/><scripttype="text/......
  • 二进制位交换,反转,与统计1的个数
    问题一:给一个整数v,求它的二进制表示中从右往左数第x位和第y位交换后的值(从0开始计数)。 分析:举个例子,如果v的二进制表示为XXXXaXXXXXXbX,我们交换第1位和第8位。我们是这样做的:先把这两位的值都取零后的值保存在一个变量里面,即tmp=XXXX0XXXXXX0X,然后再取ans=0000b000000a0,那么......
  • 求树的重心
    题目:http://poj.org/problem?id=1655题意:给定一棵树,求树的重心的编号以及重心删除后得到的最大子树的节点个数size,如果size相同就选取编号最小的.分析:首先要知道什么是树的重心,树的重心定义为:找到一个点,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心,删......
  • DP之花店橱窗布置
    题目:https://www.smartoj.com/p/1286分析:花瓶是有序的,花也是有序的,这就保证了有序性,从而满足子解的全局最优,和无后效性.假设dp[i][j]表示前i朵花,放在前j个花瓶里的最优值.则有: 那么经过优化后得到:#include<iostream>#include<string.h>#include<stdio.h>usingnamespac......
  • SBT模版(Size Balanced Tree)
    关于SBT的介绍及学习,请戳这里。 SBT模版:/*************************************************数据结构:SBT(SizeBalancedTree),又称傻逼树;数据域:值域key,左孩子left,右孩子right,保持平衡的size;性质:每棵子树的大小不小于其兄弟的子树大小;插入:插入算法先简单插入节......
  • map()和zip()操作
    对于map()它的原型是:map(function,sequence),就是对序列sequence中每个元素都执行函数function操作。比如之前的a,b,c=map(int,raw_input().split()),意思就是说把输入的a,b,c转化为整数。再比如:a=['1','2','3','4']printmap(list,a)printmap(int,a)第一个map是把列表a中每个......
  • input()与raw_input()
    首先,我们知道input()和raw_input()都是用来获取控制台的输入,当然输入的时候可以加上输入提示信息:    a=raw_input("Pleaseinputa:")    b=input("Pleaseinputb:")那么这两者有什么区别呢?input()支持用户输入数字或者表达式,不支持输入字符串,返回的......
  • 利用JSP交互式打印表格
    问题:在客户端输入要打印表格的行数rows和列数cols,然后经过服务端处理打印rows*cols的表格,打印数据为i*j。html部分:文件名:input.html<html><head><title>Hello</title></head><body><formaction="input.jsp"method="post"><tablebord......