日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2023/12/18 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [转]四边形不等式优化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

總結

以上是生活随笔為你收集整理的[转]四边形不等式优化dp(POJ1160)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。