[转]四边形不等式优化dp(POJ1160)

四边形不等式优化动态规划原理:

1.当决策代价函数w[i][j]满足w[i][j]+w[i’][j’]<=w[I;][j]+w[i][j’](i<=i’<=j<=j’),w满足四边形不等式.当函数w[i][j]满足w[i’][j]<=w[i][j’] i<=i’<=j<=j’),w关于区间包含关系单调.

2.如果状态转移方程m且决策代价w满足四边形不等式的单调函数(可以推导出m亦为满足四边形不等式的单调函数),则可利用四边形不等式推出最优决策s的单调函数性,从而减少每个状态的状态数,将算法的时间复杂度由原来的O(n^3)降低为O(n^2).方法是通过记录子区间的最优决策来减少当前的决策量.:

s[i][j]=max{k | ma[i][j] = m[i][k-1] + m[k][j] + w[i][j]}

由于决策s具有单调性,因此状态转移方程可修改为:

 

证明过程: (转载)

m[i,j]表示动态规划的状态量。

m[i,j]有类似如下的状态转移方程:

m[i,j]=opt{m[i,k]+m[k,j]}(ikj)

如果对于任意的abcd,有m[a,c]+m[b,d]m[a,d]+m[b,c],那么m[i,j]满足四边形不等式。

以上是适用这种优化方法的必要条件

对于一道具体的题目,我们首先要证明它满足这个条件,一般来说用数学归纳法证明,根据题目的不同而不同。

通常的动态规划的复杂度是O(n3),我们可以优化到O(n2)

s[i,j]m[i,j]的决策量,即m[i,j]=m[i,s[i,j]]+m[s[i,j]+j]

我们可以证明,s[i,j-1]s[i,j]s[i+1,j]  (证明过程见下)

那么改变状态转移方程为:

m[i,j]=opt{m[i,k]+m[k,j]}      (s[i,j-1]ks[i+1,j])

复杂度分析:不难看出,复杂度决定于s的值,以求m[i,i+L]为例,

(s[2,L+1]-s[1,L])+(s[3,L+2]-s[2,L+1])…+(s[n-L+1,n]-s[n-L,n-1])=s[n-L+1,n]-s[1,L]n

所以总复杂度是O(n2)

s[i,j-1]s[i,j]s[i+1,j]的证明:

mk[i,j]=m[i,k]+m[k,j]s[i,j]=d

对于任意k<d,有mk[i,j]md[i,j](这里以m[i,j]=min{m[i,k]+m[k,j]}为例,max的类似),接下来只要证明mk[i+1,j]md[i+1,j],那么只有当s[i+1,j]s[i,j]时才有可能有ms[i+1,j][i+1,j]md[i+1,j]

(mk[i+1,j]-md[i+1,j]) - (mk[i,j]-md[i,j])

=(mk[i+1,j]+md[i,j]) - (md[i+1,j]+mk[i,j])

=(m[i+1,k]+m[k,j]+m[i,d]+m[d,j]) - (m[i+1,d]+m[d,j]+m[i,k]+m[k,j])

=(m[i+1,k]+m[i,d]) - (m[i+1,d]+m[i,k])

m满足四边形不等式,∴对于i<i+1k<dm[i+1,k]+m[i,d]m[i+1,d]+m[i,k]

(mk[i+1,j]-md[i+1,j])(mk[i,j]-md[i,j])0

s[i,j]s[i+1,j],同理可证s[i,j-1]s[i,j]

证毕

扩展:

以上所给出的状态转移方程只是一种比较一般的,其实,很多状态转移方程都满足四边形不等式优化的条件。

解决这类问题的大概步骤是:

0.证明w满足四边形不等式,这里wm的附属量,形如m[i,j]=opt{m[i,k]+m[k,j]+w[i,j]},此时大多要先证明w满足条件才能进一步证明m满足条件

1.证明m满足四边形不等式

2.证明s[i,j-1]s[i,j]s[i+1,j]

pku 1160 Post Office 解题报告

题意: 给出m个村庄及其距离,给出n个邮局,要求怎么建n个邮局使代价最小.

算法:很显然用到动态规划,那么假设:

d[i…n],各邮局的坐标

w[i][j]表示在d[i][j]之间建立一个邮局的村庄为k,kij之和的一半(很显然在中间建一个邮局距离最小),那么

m[i][j]为在前j个村庄建立i个邮局的最小距离和.

那么状态转移方程为:

边界条件: m[1][j]=w[1][j]  (1<=j<=m)

状态转移方程

那么思路则为:

for i=2 to p do      //递推邮局数

{

     //m:在前j个村庄建立i个邮局的最小距离和

     for j=n dwonto i+1 do    //按递减顺序枚举尾指针

     m[i][j]=inf;

     for k=1 to n do

     {

          temp = m[i-1][k]+calcw(k+1,j);

          if(temp<m[i][j]) m[i][j]=temp;

     }

}

这样时间复杂度显然为O(n^3),这是不能接受的

仔细分析这dp算法,关键是决策变量k枚举数太多联系到四边形不等式原理,w[i][j]m[i][j]很明显符合四边形不等式,我们假设决策变量s[i][j],如果在110的村庄中,建立1个邮局的最佳位置为8,那么在决定见多一个邮局的话,当然是在18之间了(根据四边形不等式原理猜想到),所以就在dp的过程中,s[i][j]记录前i-1个邮局的村庄数. 那么我们第三次搜索的时候,就需要根据决策表s[i-1][j]<=k<=s[i][j+1]的范围内枚举.而可以证明s[i][j]具有单调性,那么我们就可以利用s[i][j]单调性限制了上下界然后把 O(n^3)弄成了 O(n^2) 

sample为例:

状态方程m:

 

决策表s:

 那么状态转移方程为:

边界条件: m[1][j]=w[1][j]  (1<=j<=m)

边界条件: m[1][j]=w[1][j]  (1<=j<=m)

状态转移方程

决策记录表: s[i][j]=k

 

代码:

View Code
//#pragma comment(linker,"/STACK:327680000,327680000")
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#include <set>
#include <functional>
#include <numeric>
#include <sstream>
#include <stack>
#include <map>
#include <queue>#define CL(arr, val)    memset(arr, val, sizeof(arr))
#define REP(i, n)       for((i) = 0; (i) < (n); ++(i))
#define FOR(i, l, h)    for((i) = (l); (i) <= (h); ++(i))
#define FORD(i, h, l)   for((i) = (h); (i) >= (l); --(i))
#define L(x)    (x) << 1
#define R(x)    (x) << 1 | 1
#define MID(l, r)   (l + r) >> 1
#define Min(x, y)   (x) < (y) ? (x) : (y)
#define Max(x, y)   (x) < (y) ? (y) : (x)
#define E(x)        (1 << (x))
#define iabs(x)     (x) < 0 ? -(x) : (x)
#define OUT(x)  printf("%I64d\n", x)
#define Read()  freopen("data.in", "r", stdin)
#define Write() freopen("data.out", "w", stdout);typedef long long LL;
const double eps = 1e-8;
const double PI = acos(-1.0);
const int inf = ~0u>>2;using namespace std;const int N = 310;
const int M = 33;int dp[N][N];
int s[N][N];
int d[N];
int sum[N][N];int dis(int i, int j) {if(i >= j)  return 0;if(sum[i][j] != 0)  return sum[i][j];int a = i, b = j;while(a < b) {sum[i][j] += (d[b--] - d[a++]);}return sum[i][j];
}int main() {//Read();int i, j, k, V, P, tmp;while(~scanf("%d%d", &V, &P)) {for(i = 1; i <= V; ++i) {scanf("%d", d + i);}CL(sum, 0);CL(dp, 0);for(i = 1;  i <= V; ++i) {dp[1][i] = dis(1, i);s[i][i] = i-1;}for(i = 2; i <= P; ++i) {s[i][V+1] = V-1;for(j = V; j >= i; --j) {dp[i][j] = inf;for(k = s[i-1][j]; k <= s[i][j+1]; ++k) {tmp = dp[i-1][k] + dis(k + 1, j);if(tmp < dp[i][j]) {dp[i][j] = tmp;s[i][j] = k;}}}}printf("%d\n", dp[P][V]);}return 0;
}

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/vongang/archive/2013/01/21/2869315.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/461428.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode27——Remove Element(移除数组中指定的元素)

题目&#xff1a; 解法&#xff1a; class Solution { public:int removeElement(vector<int>& nums, int val) {int cnt 0;for(int i 0 ; i < nums.size() ; i) {if(nums[i] val)cnt;elsenums[i-cnt] nums[i];//这里体现了删除。画图表示&#xff08;2不是&a…

inputstream的大小为0_刘科排列三第2020306期推荐:独胆参考0,双胆0和7

排列三第2020305期奖号开出373&#xff0c;奖号类型为组三&#xff0c;大小比为1:2&#xff0c;奇偶比为3:0&#xff0c;012路比为2:1:0。 组选类型推荐&#xff1a;历史上排列三第306期同期奖号中&#xff0c;组六出现10期&#xff0c;组三出现4次&#xff0c;豹子出现1期&…

ARM指令集(下)

A.2.5 ARM 协处理器指令 ARM 支持协处理器操作&#xff0c;协处理器的控制要通过协处理器命令实现。表A-7给出全部的ARM协处理器指令。 表A-7 ARM 协处理器指令CDP 协处理器数据操作指令。ARM 处理器通过CDP 指令通知ARM 协处理器执行特定的操作。该操作由协…

LeetCode283——Move Zeroes(将0移动到数组最后面)

题目&#xff1a; 解法&#xff1a; class Solution { public:void moveZeroes(vector<int>& nums) {fill(remove(nums.begin(), nums.end(),0), nums.end(), 0);} }; oh&#xff0c;no&#xff01;解法二&#xff1a; void moveZeroes(vector<int>& nums)…

java关闭一个窗口打开另一个_推开中式门窗,就像打开了另一个写意的世界…...

导语“湖光秋枕上&#xff0c;岳翠夏窗中。”在传承几千年的中式建筑文化中&#xff0c;自古以来就有多门窗、少实墙的传统&#xff0c;虚虚实实之间讲究内外空间融合&#xff0c;借景框景之时彰显人与自然和谐&#xff0c;门窗甚至直接决定着整体建筑的风格气质。随着时代的不…

同样是面对失败的责任:任春雷比杜一楠更有种

24 券创始人杜一楠最近成为热点人物&#xff0c;他的一篇“悔过书”引发各大媒体上万次的转载。一夜之间&#xff0c;这位与资方博弈的爷们儿却变成了一个负面人物&#xff0c;让人始料不及。业界人士评价说&#xff0c;这份“失败总结”满篇都是假大空&#xff0c;所总结的六点…

PopStar(消灭星星)游戏源代码下载、分析及跨平台移植---第四篇(关卡)

背景&#xff1a;本来打算把第三篇和第四篇合并都一起&#xff0c;但以前计划分开&#xff0c;就还是分来吧&#xff1b;一般的游戏涉及到关卡的话&#xff0c;一般都会建立一个数组来存放各种定义参数&#xff0c;消灭星星关卡比较容易&#xff0c;不需要建立数组&#xff0c;…

LeetCode344——Reverse String(将字符串反转)

题目&#xff1a; 解法&#xff1a; class Solution { public:string reverseString(string s) {int i0,js.size()-1;while(i<j){swap(s[i],s[j--]);}return s; } };

Thinkphp带表情的评论回复实例

Thinkphp带表情的评论回复实例 基于Thinkphp开发的一个简单的带表情的评论回复实例&#xff0c;可以无限回复&#xff0c;适合新手学习或作为毕业设计作品等。 评论提交验证 1 $(".submit-btn").click(function() { 2 var $this $(this); 3 var name $th…

amd cpu不能在cmd环境下运行java代码_「我们一起学Java02」JDK、JRE、JVM简介,Java开发平台的搭建...

Hello&#xff0c;各位头条的读者大家好&#xff01;接下来一段时间小编将和大家一起学习Java&#xff0c;“我们一起学Java”专题将会持续更新&#xff0c;欢迎大家关注。这里是“我们一起学Java”的第二篇&#xff0c;本文主要内容&#xff1a;1.JDK、JRE、JVM的简单介绍2.JD…

让Microsoft Web Application Stress Tool 支持非80端口的站点测试

刚在做内网内某个项目的性能测试 项目部署的端口为4000 然后用Microsoft Web Application Stress Tool 测试 发现居然不支持非80端口 找遍整个配置界面没发现port选项 寻思着会不会是写到配置文件里呢 于是打开安装目录寻找 苍天不负有心人 居然找到了WAS.mdb 这个文件 停掉web…

LeetCode20——Valid Parentheses(括号匹配问题,使用栈的知识)

题目&#xff1a; 解法&#xff1a; #include <stack>class Solution { public:bool isValid(string s) {stack<char> paren;for (char& c : s) {switch (c) {case (: case {: case [: paren.push(c);break;case ): if (paren.empty() || paren.top()!() retur…

取周一时间_周一到周五不好化妆?别着急,5款夏日通勤裸妆的教程来了!

化妆已经成为了许多女生每天的必修课&#xff0c;好的妆容不仅可以让自己显得有精神还可以增添自己的自信。但是每天早上起来&#xff0c;能够化妆的时间又不多&#xff0c;所以只好每天都重复同一样妆容&#xff0c;快速便捷&#xff0c;时间久了就渐渐感觉了无生趣。尤其是周…

LeetCode22——Generate Parentheses(给定n对括号,然后看有多少正确的括号组合)

题目&#xff1a; 解法&#xff1a; The idea is intuitive. Use two integers to count the remaining left parenthesis (n) and the right parenthesis (m) to be added. At each function call add a left parenthesis if n >0 and add a right parenthesis if m>0.…

docker安装mysql_Docker 安装 MySQL

本篇将介绍如何使用 Docker 部署 MySQL 数据库及远程访问配置。安装 MySQL拉取镜像使用下面的命令拉取 MySQL 数据库的镜像&#xff1a;$ sudo docker pull mysql # 拉取最新版本的镜像&#xff0c;当前为 MySQL 8 版本&#xff0c;tag 为 latest$ sudo docker pull mysql:5.7…

LeetCode17——Letter Combinations of a Phone Number(手机几个按键对应的字母(符号)组合)

题目&#xff1a; 解法&#xff1a; Simple and efficient iterative solution. Explanation with sample input "123" Initial state: result {""} Stage 1 for number "1": result has {""}candiate is "abc"generate …

python人人语音爬虫(登陆尚未完成,需要使用先登录在查cookie中的t)

2019独角兽企业重金招聘Python工程师标准>>> import urllib, urllib2, cookielib,re,jsondef LoginRenren(url,t_cookie):cookie {"t": t_cookie}#cookie中的t需要到浏览器中去查cookie "".join(x "" cookie[x] ";" f…

IDEA将项目打包为指定class文件的jar

转自&#xff1a;https://blog.csdn.net/makang456/article/details/86699375 【背景】 公司最近要和某大公司合作&#xff0c;将本公司的产品提供给其它公司单独部署售卖&#xff0c;为了让产品中重要的服务具备防君子不防小人的作用&#xff0c;于是就写了一个单独的服务…

鼠标点击实现花瓣雨_每周实验 | 黄金雨

点击BNU化学学社快来关注我们吧&#xff01;倩西风染就丹砂。不比黄金雨&#xff0c;灿余霞。送幽梦&#xff0c;到仙家。背景介绍BACKGROUND在开始实验之前&#xff0c;我们先来看一种植物&#xff0c;阿勃勒。它是苏木科决明属的落叶大乔木&#xff0c;花朵是最重要的观赏特征…

大规模天线阵列(massive-mimo)的介绍

本文转载于http://www.sohu.com/a/106043955_114877&#xff0c;如有侵权&#xff0c;请告知删除。有删改。 前言 这是最好的时代&#xff0c;也是最坏的时代。 生活在科技大爆发的时代里&#xff0c;你是否感觉到一丝庆幸? 虚拟现实、自动驾驶&#xff0c;无数令人血脉偾张…