POJ 1160 (区间DP+四边形优化)

这个转移方程不好想,尤其是一段值的解是中间,不明觉厉。dp[i][j] 用i个邮局,覆盖前j个村庄的最小值。

还有就是区间dp的平行四边形优化,这个题的转移方程并不是“区间DP”,所以枚举状态要逆着(很花时间),且用一个邮局覆盖都是从0断开了相当于没有断开。

类比于石子归并,矩阵链乘等标准区间DP,其所需状态之前就已经获得,不用倒推

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;

const int NN=310;
const int INF=0x7fffffff;

int n,m;
int s[NN],dp[NN][NN],w[NN][NN],p[NN][NN];

void get_w()//求在i~j号村庄间建一个邮局的最小距离和
{
    for (int i=1; i<n; i++)
      for (int j=i+1; j<=n; j++)
      {
          if ((i+j)%2) w[i][j]=s[j]-s[(i+j)/2]*2+s[i-1];
          else         w[i][j]=s[j]-s[(i+j)/2]-s[(i+j)/2-1]+s[i-1];
      }
}

void get_dp()
{
    for (int i=1; i<=n; i++)
    {
        dp[1][i]=w[1][i];
        p[1][i]=0;//注意这里
    }
    for (int c=2; c<=m; c++)
    {
        p[c][n+1]=n;
        for (int i=n; i; i--)///这里倒着写,p[c][i+1]是取后面值
        {
            int tmp=INF,k;
            for (int j=p[c-1][i]; j<=p[c][i+1]; j++)
            {
                if (dp[c-1][j]+w[j+1][i]<tmp) tmp=dp[c-1][k=j]+w[j+1][i];
            }
            dp[c][i]=tmp;
            p[c][i]=k;
        }
    }
}

int main()
{
    scanf("%d%d",&n,&m);
    s[0]=0;
    int x;
    for (int i=1; i<=n; i++)
    {
        scanf("%d",&x);
        s[i]=s[i-1]+x;
    }
    get_w();
    get_dp();
    printf("%d",dp[m][n]);
    return 0;
}
//直线取石子问题的平行四边形优化:

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

using namespace std;
const int INF = 1 << 30;
const int N = 1005;

int dp[N][N];
int p[N][N];
int sum[N];
int n;

int getMinval()
{
    for(int i=1; i<=n; i++)
    {
        dp[i][i] = 0;
        p[i][i] = i;//这个自己跟自己乘自然是以自己为分割了。
    }
    for(int len=1; len<n; len++)
    {
        for(int i=1; i+len<=n; i++)
        {
            int end = i+len;
            int tmp = INF;
            int k = 0;
            for(int j=p[i][end-1]; j<=p[i+1][end]; j++)
            {
                if(dp[i][j] + dp[j+1][end] + sum[end] - sum[i-1] < tmp)
                {
                    tmp = dp[i][j] + dp[j+1][end] + sum[end] - sum[i-1];
                    k = j;
                }
            }
            dp[i][end] = tmp;
            p[i][end] = k;
        }
    }
    return dp[1][n];
}

int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        sum[0] = 0;
        for(int i=1; i<=n; i++)
        {
            int val;
            scanf("%d",&val);
            sum[i] = sum[i-1] + val;
        }
        printf("%d\n",getMinval());
    }
    return 0;
}
时间: 2024-11-06 17:15:58

POJ 1160 (区间DP+四边形优化)的相关文章

51Nod 1022 石子归并 V2(区间DP+四边形优化)

题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1022 题目大意: N堆石子摆成一个环.现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的代价.计算将N堆石子合并成一堆的最小代价. 例如: 1 2 3 4,有不少合并方法 1 2 3 4 => 3 3 4(3) => 6 4(9) => 10(19) 1 2 3 4 => 1 5 4(5)

HDU 3506 (环形石子合并)区间dp+四边形优化

Monkey Party Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Total Submission(s): 1699    Accepted Submission(s): 769 Problem Description Far away from our world, there is a banana forest. And many lovely monkeys l

hdu3516 Tree Construction (区间dp+四边形优化)

构造方法肯定是把相邻两个点连到一起,变成一个新点,然后再把新点和别的点连到一起.... 设f[i,j]为把第i到j个点都连到一起的代价,那么答案就是f[1,n] f[i,j]=min{f[i,k]+f[k+1,j]+x[k+1]-x[i]+y[k]-y[j]} (画一画就知道了) 然后显然满足四边形不等式(怎么就显然了??) 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include&l

区间dp+四边形不等式优化

区间dp+四边形优化 luogu:p2858 题意 给出一列数 \(v_i\),每天只能取两端的数,第 j 天取数价值为\(v_i \times j\),最大价值?? 转移方程 dp[i][j] :n天卖掉i..j货物的收益 dp[begin][end]=max(dp[begin][end-1]+value[end]*(n-len+1) ,dp[begin+1][end]+value[begin]*(n-len+1)); 注意理解 代码 递推形式 #include<bits/stdc++.h>

POJ 1160 Post Office (四边形不等式优化DP)

题意: 给出m个村庄及其距离,给出n个邮局,要求怎么建n个邮局使代价最小. 析:一般的状态方程很容易写出,dp[i][j] = min{dp[i-1][k] + w[k+1][j]},表示前 j 个村庄用 k 个邮局距离最小,w可以先预处理出来O(n^2),但是这个方程很明显是O(n^3),但是因为是POJ,应该能暴过去..= =,正解应该是对DP进行优化,很容易看出来,w是满足四边形不等式的,也可以推出来 s 是单调的,可以进行优化. 代码如下: #pragma comment(linker,

POJ 1160 Post Office(四边形不等式优化)

四边形不等式 函数w满足 1: 区间包含的单调性,对于\(x1<x2<y1<y2\),有\(w[x2][y1] < w[x1][y2]\) 2: 四边形不等式,对于\(x1<x2<y1<y2\),有\(w[x1][y1]+w[x2][y2] < w[x1][y2]+w[x2][y1]\) 则函数m(其最优选择)也满足四边形不等式. 对于满足四边形不等式的函数,是满足单调性的(x方向单调,y方向也单调),可以通过判断dp是否满足四边形不等式,也可以用来优化转移

hdu 3506 Monkey Party 区间dp + 四边形不等式优化

http://acm.hdu.edu.cn/showproblem.php?pid=3506 四边行不等式:http://baike.baidu.com/link?url=lHOFq_58V-Qpz_nTDz7pP9xCeHnd062vNwVT830z4_aQoZxsCcRtac6CLzbPYLNImi5QAjF2k9ydjqdFf7wlh29GJffeyG8rUh-Y1c3xWRi0AKFNKSrtj3ZY7mtdp9n5W7M6BBjoINA-DdplWWEPSK#1 dp[i][j]表示第

蓝桥杯:合并石子(区间DP+平行四边形优化)

http://lx.lanqiao.cn/problem.page?gpid=T414 题意:…… 思路:很普通的区间DP,但是因为n<=1000,所以O(n^3)只能拿90分.上网查了下了解了平行四边形优化:地址. 但是看不懂. 1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 const LL INF = 100000000000000000LL; 5 LL dp[1010][101

poj 3280(区间DP)

Cheapest Palindrome Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7869   Accepted: 3816 Description Keeping track of all the cows can be a tricky task so Farmer John has installed a system to automate it. He has installed on each cow a