DP——最优矩阵链乘最优三角剖分
最優(yōu)矩陣鏈乘:
一個(gè)n*m的矩陣乘一個(gè)m*p的矩陣等于一個(gè)n*p的矩陣,運(yùn)算量為mnp,現(xiàn)在有一組n個(gè)矩陣組成的序列,求運(yùn)算量的最小值。
這是DP中的最優(yōu)矩陣鏈乘問(wèn)題,我們可以這么理解:用一個(gè)d[i][j]來(lái)存儲(chǔ)第i個(gè)矩陣鏈乘到第j個(gè)矩陣的最優(yōu)解,那么現(xiàn)在進(jìn)行DP化,也就是找它的子解。我們把這組序列從中間不同位置裂開(kāi),記這個(gè)位置為k,那么不難得到d[i][j]=d[i][k]+d[k+1][j]+p[i-1]*p[k]*p[j],根據(jù)最優(yōu)化原則,如果d[i][k]和d[k+1][j]都已經(jīng)是最優(yōu)解,那么我們只要取k為某值時(shí)d[i][j]為最小即可。
可以寫(xiě)出狀態(tài)轉(zhuǎn)移方程:d[i][j] = min(d[i][j], d[i][k] + d[k + 1][j] + p[i - 1] * p[k] * p[j]),但要注意,這里如果用遞推,i和j都是很難取的,因?yàn)檫@按i和j的區(qū)間遞推的,所以我們按照j-i遞增的順序遞推,長(zhǎng)區(qū)間的值依賴(lài)與小區(qū)間的值。邊界條件是d[i][i]=0。
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<algorithm> using namespace std; int n; int d[105][105],p[105];int main() {int i, j,k,l;while (~scanf("%d", &n)){for (i = 1; i <= n; i++)scanf("%d%d", &p[i - 1], &p[i]);for (i = 1; i <= n; i++)d[i][i] = 0;for (l = 2; l <= n; l++)//按照j-i也就是區(qū)間的長(zhǎng)度來(lái)遞推{for (i = 1; i <= n - l + 1; i++){j = i + l - 1;d[i][j] = 0xfffffff;for (k = i; k <= j - 1; k++)d[i][j] = min(d[i][j], d[i][k] + d[k + 1][j] + p[i - 1] * p[k] * p[j]);}}printf("%d\n", d[1][n]);}return 0; }最優(yōu)三角剖分:
對(duì)于一個(gè)n個(gè)頂點(diǎn)的凸三角形,用n-3條互不相交的對(duì)角線(xiàn)將其分成n-2個(gè)三角形,為每個(gè)三角形規(guī)定一個(gè)權(quán)函數(shù)w(i,k,j)(三角形的周長(zhǎng)),求讓所以三角形權(quán)值和最小的值。 還是區(qū)間DP的原理,從區(qū)間中找k,切出一個(gè)三角形和兩個(gè)子多邊形,進(jìn)行DP即可,注意這里的邊界為d[i][i]=d[i][i+1]=0。 狀態(tài)轉(zhuǎn)移方程為:d[i][j] = min(d[i][j], d[i][k] + d[k][j] + w(i, k, j)),i<k<j。 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<algorithm> using namespace std; const int n = 6; int w[][n] = { { 0,2,2,3,1,4 },{ 2,0,1,5,2,3 },{ 2,1,0,2,1,4 },{ 3,5,2,0,6,2 },{ 1,2,1,6,0,1 },{ 4,3,4,2,1,0 } }; int d[10][10];int get_weight(int a, int b, int c) {return (w[a][b] + w[a][c] + w[b][c]); }int main() {int i, j, l, k;for (i = 0; i <= n; i++)//邊界條件{d[i][i] = 0;d[i][i + 1] = 0;}for (l = 2; l < n; l++){for (i = 0; i + l <= n-1; i++){j = i + l;d[i][j] = 0xffffff;for (k = i + 1; k < j; k++)d[i][j] = min(d[i][j], d[i][k] + d[k][j] + get_weight(i, k, j));}}printf("%d\n", d[0][n - 1]);return 0; }轉(zhuǎn)載于:https://www.cnblogs.com/seasonal/p/10343738.html
總結(jié)
以上是生活随笔為你收集整理的DP——最优矩阵链乘最优三角剖分的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 在eclipse里配置Android n
- 下一篇: Spark-ML-数据获取/处理/准备