poj1161Post Office【经典dp】

题目:poj1161Post Office点击打开链接

题意:给出一条直线上的n个坐标表示村庄的位置,然后要在上面建p个邮局,村民优先选择去近的邮局,问所有村庄去邮局的最小距离和是多少?

分类:区间dp

分析:对于任意一个村庄,只有两种选择,要么在这儿建邮局,要么不建,我们可以预处理出来任意两件建立一个邮局的的最小距离w【i】【j】,而对于任意两点,建立一个邮局的最优方案是建立在两点的中位数上,即(i+j)/2,位置。

对于任意两点 i---j ,建立两个邮局的最优结果我们可以由建立一个的得到,枚举分点,然后从中间分开,前面建一个,后面建一个。那么我们就可以写出状态及方程

定义状态:dp【i】【j】表示在前 i 个存在建立 j 个邮局的最小距离。

转移方程:dp【i】【j】=min(dp【i】【j】,dp【k】【j-1】+w【k+1】【i】) (j-1<=K<=i-1)

注意:

1:这个题目的dp方向是邮局数目,不是村庄数目,有建立邮局的数目1----p的方向dp

2:注意dp初始化后,其他值一定在循环内部初始化,否则不一定最优、

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <map>
#include <cmath>
using namespace std;
#define Del(a,b) memset(a,b,sizeof(a))
const int N = 500;
int w[N][N];
int dp[N][45];
int dis[N];

int main()
{
    //freopen("Input.txt","r",stdin);
    int n,k;
    while(~scanf("%d%d",&n,&k))
    {
        for(int i=1;i<=n;i++)
            scanf("%d",&dis[i]);
        Del(w,0);
        for(int i=1;i<=n;i++)
        {
            for(int j=i+1;j<=n;j++)
            {
                w[i][j] = w[i][j-1]+  dis[j]  -  dis[(i+j)/2];
            }
            //printf("\n");
        }
        Del(dp,0x3f3f3f3f);
        for(int i=1;i<=n;i++)
        {
            dp[i][1]=w[1][i];
            dp[i][i]=0;
        }
        for(int j=2;j<=k;j++)
        {
            for(int i=j+1;i<=n;i++)
            {
                dp[i][j]=0x3f3f3f3f;//注意标准写法
                for(int f=j-1;f<=i-1;f++)
                    dp[i][j]=min(dp[i][j],dp[f][j-1]+w[f+1][i]);
            }
        }
        printf("%d\n",dp[n][k]);
    }
    return 0;
}

poj1161Post Office【经典dp】

时间: 2024-09-29 01:18:44

poj1161Post Office【经典dp】的相关文章

POJ 1160 Post Office 经典DP + 四边形加速

第一次写四边形不等式的题,现在的理解就是用各种东东缩小了k的范围,从而使复杂度降低到n^2 需要满足的条件是 对于i<i'<j<j' 满足 w(i,j)+w(i',j') <= w(i,j') + w(i'j) #include <cstdio> #include <cstring> #include <algorithm> #include <cstdlib> #include <map> #include <se

POJ 1160:Post Office 邮局经典DP

Post Office Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 17168   Accepted: 9270 Description There is a straight highway with villages alongside the highway. The highway is represented as an integer axis, and the position of each villa

pku 1160 Post Office 四边形不等式优化 经典DP

pku 1160 Post Office 四边形不等式优化 经典DP 邮局 经典的动态规划问题,主要体现在状态的设计和可以用四边形不等式优化上 题意是:给你n个村庄,然后让你用m个邮局对这些村庄进行覆盖,然后让你设计覆盖方式使得每个村庄到其对应邮局的路程和最短 本题状态的设计的灵感来源于"覆盖"这个点,最优子结构其实就是用 m 个邮局覆盖,以及用 m-1个邮局覆盖 那么,状态为dp[n][m] 为前 n 个村庄用 m 个邮局进行覆盖使得每个村庄到其对应的邮局的最短路程和 转移方程:dp

51nod 1412 AVL树的种类(经典dp)

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1412 题意: 思路: 经典dp!!!可惜我想不到!! $dp[i][k]$表示i个结点,最大深度为k的形态数. 它的转移方程就是: dp[i][k] += dp[i - 1 - j][k - 1] * dp[j][k - 1] dp[i][k] += 2 * dp[i - 1 - j][k - 2] * dp[j][k - 1] j是右子树结点个数,如果除去根结点,是不

NYOJ 16 矩形嵌套(经典DP)

http://acm.nyist.net/JudgeOnline/problem.php?pid=16 矩形嵌套 时间限制:3000 ms  |           内存限制:65535 KB 难度:4 描述 有n个矩形,每个矩形可以用a,b来描述,表示长和宽.矩形X(a,b)可以嵌套在矩形Y(c,d)中当且仅当a<c,b<d或者b<c,a<d(相当于旋转X90度).例如(1,5)可以嵌套在(6,2)内,但不能嵌套在(3,4)中.你的任务是选出尽可能多的矩形排成一行,使得除最后一个

最长上升子序列--经典dp

最长上升子序列 Time Limit: 3000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 一个数的序列bi,当b1 < b2 < ... < bS的时候,我们称这个序列是上升的.对于给定的一个序列(a1, a2, ..., aN),我们可以得到一些上升的子序列(ai1, ai2, ..., aiK),这里1<= i1 < i2 < ... < iK <= N.比如,对于序列(1, 7, 3, 5, 9, 4, 8)

soj 1033 City Road_经典dp

题目链接 题意:给你一个n*m的图,给你b个矩形(在图中,不能通过),只能向上和右走,问左下角到右上角有多少种走法. 思路:经典的dp,dp[i][j]=max(dp[i-1][j],dp[i][j-1]),但是n*m实在太大,不可能直接开这么大的数组,想一下只需要两行的数据就能求出最优解,所以用滚动数组. dp[k][j]=max(dp[1-k][j],dp[k][j-1]),k代表当前行,1-k代表前一行. #include <iostream> #include<cstdio>

Codeforces 176B 经典DP

非常好的一个题目,CF上的DP都比较经典 题意就是 给定一个串A,B,正好执行K次操作,每次操作可以把 A串从中间切开,并调换两部分的位置,问最后得到B串共有多少种不同的切法(只要中间有一次不同,即视为不同) 首先,题目的一个关键点一定要抓到,就是 ,不管怎么切 然后调换位置,其实串根本没变,你把串想成一个环,从某一点分成两部分并且交换位置,其实就是把串的起点变到了该点,这是很关键也是最机智的一点 然后,我们要发现规律,你纸上模拟也行,推理也行.. 我们发现:1.首先原串(即以0号字母开头的)个

NYOJ - 矩形嵌套(经典dp)

矩形嵌套时间限制:3000 ms | 内存限制:65535 KB 描述 有n个矩形,每个矩形可以用a,b来描述,表示长和宽.矩形X(a,b)可以嵌套在矩形Y(c,d)中当且仅当a<c,b<d或者b<c,a<d(相当于旋转X90度).例如(1,5)可以嵌套在(6,2)内,但不能嵌套在(3,4)中.你的任务是选出尽可能多的矩形排成一行,使得除最后一个外,每一个矩形都可以嵌套在下一个矩形内. 输入第一行是一个正正数N(0<N<10),表示测试数据组数,每组测试数据的第一行是一