我很努力去理解線性分區問題的動態編程解決方案。我正在閱讀The Algorithm Design Manual,問題在第8.5節中描述。我已經讀了無數次的部分,但我只是沒有得到它。我認爲這是一個糟糕的解釋(我現在閱讀的內容已經好多了),但我無法很好地理解這個問題以尋找替代解釋。更好的解釋鏈接歡迎!如何理解線性分區中的動態規劃解決方案?
我發現了一個頁面,其文字與本書相似(可能來自本書的第一版):The Partition Problem。
第一個問題:在本書的例子中,分區按從小到大的順序排列。這只是巧合嗎?從我所能看到的元素排序對算法來說並不重要。
這是我的遞歸的理解:
讓我們用下面的序列,並將其劃分爲4:
{S1...Sn} = 100 150 200 250 300 350 400 450 500
k = 4
第二個問題:我是這樣認爲的遞歸將開始 - 有我的理解是是否正確?
第1遞歸是:
100 150 200 250 300 350 400 450 | 500 //3 partition to go
100 150 200 250 300 350 400 | 450 | 500 //2 partition to go
100 150 200 250 300 350 | 400 | 450 | 500 //1 partition to go
100 150 200 250 300 | 350 | 400 | 450 | 500 //done
第2遞歸是:
100 150 200 250 300 350 400 450 | 500 //3 partition to go
100 150 200 250 300 350 400 | 450 | 500 //2 partition to go
100 150 200 250 300 350 | 400 | 450 | 500 //1 partition to go
100 150 200 250 | 300 350 | 400 | 450 | 500 //done
第三遞歸是:
100 150 200 250 300 350 400 450 | 500 //3 partition to go
100 150 200 250 300 350 400 | 450 | 500 //2 partition to go
100 150 200 250 300 350 | 400 | 450 | 500 //1 partition to go
100 150 200 | 250 300 350 | 400 | 450 | 500 //done
第四遞歸是:
100 150 200 250 300 350 400 450 | 500 //3 partition to go
100 150 200 250 300 350 400 | 450 | 500 //2 partition to go
100 150 200 250 300 350 | 400 | 450 | 500 //1 partition to go
100 150 | 200 250 300 350 | 400 | 450 | 500 //done
第五遞歸是:
100 150 200 250 300 350 400 450 | 500 //3 partition to go
100 150 200 250 300 350 400 | 450 | 500 //2 partition to go
100 150 200 250 300 350 | 400 | 450 | 500 //1 partition to go
100 | 150 200 250 300 350 | 400 | 450 | 500 //done
第六遞歸是:
100 150 200 250 300 350 400 450 | 500 //3 partition to go
100 150 200 250 300 350 400 | 450 | 500 //2 partition to go
100 150 200 250 300 | 350 400 | 450 | 500 //1 partition to go
100 150 200 250 | 300 | 350 400 | 450 | 500 //done
第七遞歸是:
100 150 200 250 300 350 400 450 | 500 //3 partition to go
100 150 200 250 300 350 400 | 450 | 500 //2 partition to go
100 150 200 250 300 | 350 400 | 450 | 500 //1 partition to go
100 150 200 | 250 300 | 350 400 | 450 | 500 //done
第八遞歸是:
100 150 200 250 300 350 400 450 | 500 //3 partition to go
100 150 200 250 300 350 400 | 450 | 500 //2 partition to go
100 150 200 250 300 | 350 400 | 450 | 500 //1 partition to go
100 150 | 200 250 300 | 350 400 | 450 | 500 //done
第九遞歸是:
100 150 200 250 300 350 400 450 | 500 //3 partition to go
100 150 200 250 300 350 400 | 450 | 500 //2 partition to go
100 150 200 250 300 | 350 400 | 450 | 500 //1 partition to go
100 | 150 200 250 300 | 350 400 | 450 | 500 //done
等等
下面的代碼,因爲它出現在書:
partition(int s[], int n, int k)
{
int m[MAXN+1][MAXK+1]; /* DP table for values */
int d[MAXN+1][MAXK+1]; /* DP table for dividers */
int p[MAXN+1]; /* prefix sums array */
int cost; /* test split cost */
int i,j,x; /* counters */
p[0] = 0; /* construct prefix sums */
for (i=1; i<=n; i++) p[i]=p[i-1]+s[i];
for (i=1; i<=n; i++) m[i][3] = p[i]; /* initialize boundaries */
for (j=1; j<=k; j++) m[1][j] = s[1];
for (i=2; i<=n; i++) /* evaluate main recurrence */
for (j=2; j<=k; j++) {
m[i][j] = MAXINT;
for (x=1; x<=(i-1); x++) {
cost = max(m[x][j-1], p[i]-p[x]);
if (m[i][j] > cost) {
m[i][j] = cost;
d[i][j] = x;
}
}
}
reconstruct_partition(s,d,n,k); /* print book partition */
}
關於該算法:
- 什麼值存儲在
m
和d
? - '成本'是什麼意思?它只是分區內元素值的總和?或者還有一些更微妙的含義?
順便說一句,即使你不能回答我的問題,我將不勝感激關於源材料質量的評論。我希望得到一些確認,不僅僅是我認爲解釋不好(這讓我感覺相當不舒服)。 –
我不認爲你會發現很多人在這裏能夠回答你的問題,而無需對你需要解決的問題給出一個簡潔的解釋。分區問題有很多種變化,並且粘貼由手動執行的算法的長表並不會讓事情變得更清楚。 – hugomg