动态规划 dp04 凸n边形的三角形划分 c代码
先看題目:
給定凸n邊形P = {1,2,,,n},每一個頂點i帶一個權數r(i)(i = 1,2,,,n)。要求在該凸n邊形的頂點間連n-3條互不相交的連線, 把凸N邊形分成n-2個三角形,每個三角形的值為其三個頂點權數之積。試確定一種三角形剖分,使得剖分的n-2個三角形的值之和最小。如下圖,凸6邊形,頂點序號分別為1-6,頂點的權數未在圖中標出。
這道題還是相當有難度的,第一次沒做出來,看講解懂了。第二次做的時候又卡在一個地方......,沒理解透徹,就又看了一遍。稍微明白了。常規的動態規劃類題目階段都是很明顯,比如說背包問題,每個物品就是一個階段,但是本題目就不是那么明顯了,至少對我來說。不清楚階段沒關系,繼續做題,設i,j分別表示途中頂點,m[i][j]表示所劃分的最大值,顯而易見
m[i][i+2] = i * (i+1) * (i+2); m[i][j] = Max(m[i][k]+m[k][j]+i*j*k),其中i < k < j; 狀態遷移方程是如此簡潔,讓多次思考沒能想出的我有點懷疑智商,多看幾遍也還是能夠理解的,即便第一次不會,下一次遇到能夠會做也行。這樣的狀態遷移方程和最長非降子數列問題類似。通過求解子問題,遍歷得到最大值。邊界情況就是m[i][i+1] = 0。利用此方法,上圖的最優解是m[1][6],得到了最優解,需要知道最有子序列的值,這時候從后往前遍歷頂點序列,找到最大的m[i][k],k即是分割點,接著遞歸遍歷[i][k]和[k][j]即可。
此外的一個難點就是,雖然知道了狀態遷移方程,但是要注意,求取m[i][j]的時候,需要先求出[i][k]和[k][j],這一點尤其值得注意,和普通的動態規劃不一樣,在設置循環的時候應該注意這點。
本題目略微有難度,看不懂的同學需要多多編碼調試才行。
下面是c代碼實現:
/** N凸邊形劃分三角形,求所得所有的三角形頂點之積的最大值* m[i][j] = MAX(m[i][k] + m[k][j] + a[i]*a[k]*a[j])*/#include <stdio.h>void showEdage(int (*p)[30], int i, int j) {int k;k = p[i][j];if (j <= i + 1)return;if (k > i + 1)printf("%d - %d ", i, k);if (k < j - 1) printf("%d - %d ", k, j);showEdage (p, i, k);showEdage (p, k, j); }void main() {int i, j, k, d, n, a[30] = {0}, m[30][30] = {0}, c[30][30] = {0};printf("input nTriangle's n:"); scanf("%d", &n);if (n > 30){printf("invalid n\n");return;}for (i = 0; i < n; i++){printf("input %d value:", i+1);scanf("%d", &a[i]);}printf("you input n :%d \nvertex: ",n);for (i = 0; i < n; i++)printf("%d ", a[i]);//邊界初始化for (i = 0; i < n - 1; i++)m[i][i+1] = 0;//遞推求解for (d = 2; d < n; d++)for (i = 0; i <= n - d - 1; i++){j = i + d;m[i][j] = 10000000;for (k = i + 1; k < j; k++){if (m[i][j] > m[i][k] + m[k][j] + a[i] * a[j] * a[k]){m[i][j] = m[i][k] + m[k][j] + a[i] * a[j] * a[k];c[i][j] = k;} } }//打印最優解printf("Min : %d\n", m[0][n-1]);showEdage (c, 0, n-1); }參考資料:
1.?數據結構?: C語言版/ 嚴蔚敏,吳偉民編著
=============================================================================================
Linux應用程序、內核、驅動開發交流討論群(745510310),感興趣的同學可以加群討論、交流、資料查找等,前進的道路上,你不是一個人奧^_^。
總結
以上是生活随笔為你收集整理的动态规划 dp04 凸n边形的三角形划分 c代码的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 动态规划 dp03 最长公共子串问题 c
- 下一篇: 动态规划 dp05 插入乘号问题 c代码
