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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

POJ-1651 Multiplication Puzzle 矩阵连乘问题(区间dp)

發布時間:2023/12/10 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 POJ-1651 Multiplication Puzzle 矩阵连乘问题(区间dp) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題意

給我們n個數 讓我們隨意的跳出其中的數 每挑出一個數 計算代價為左邊數* 當前數 * 右邊的數
除了首尾兩個數不選 中間的數可以任意挑 讓我們求最小代價

CODE

#include<bits/stdc++.h> using namespace std; int a[110],m[110][110]; const int maxn = 0x7f7f7f; int main() {int n;scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",&a[i]);for(int i=1;i<=n;i++)m[i][i]=0;for(int l=2;l<n;l++){// 區間長度從2開始 1沒意義 for(int i=1;i<=n-l+1;i++){// 起始點從2 開始 int j = i+l-1;m[i][j] = maxn;// cout<<"L:"<<l<<" "<<i<<" "<<j<<":"<<endl;for(int k = i;k<j;k++){// 枚舉最后一個選擇的位置 int t = m[i][k]+m[k+1][j]+a[i-1]*a[k]*a[j];//本次結果就是從i到k連起來的最小+從k+1到j連起來的最小+本次連起來后的代價 // cout<<i-1<<" "<<k<<" "<<j<<" "<<t<<endl;m[i][j] = min(t,m[i][j]);// system("pause");}}}printf("%d\n",m[2][n]);return 0; }

分析

這道題開始看非常蒙
這該怎么做?
其實這道題可以轉化成矩陣連乘問題
我們定義從i到j的最小代價 其實就是從i 到k + 從k+1 到j的最小代價 + 中間分割的k的代價 把i到j之間的k枚舉一遍取最小
所以就得到了兩個子問題
我們知道兩個矩陣相乘總計算量就是p* r * q(p*r,r * q的兩個矩陣)
有沒有發現這里有點相似
每相鄰的兩個數 就是矩陣的行和列
第i個矩陣式子為 a[i-1]*a[i]
所以從起始點從2開始才有意義
如果其實點從1開始沒意義(a[i-1]為0 那么計算量為0)
第一個矩陣為前兩個元素 開始那么他的參數就是
a[1]?a[2]
所以這道題我們刪掉一個元素時 或是從中心合并兩個結果時
加上額外的代價
也就是a[i?1]?a[k]?a[j]
這個就是 、
第一個矩陣 a[i?1]?a[k]
第二個矩陣a[k]?a[j]
那么其抽象計算量就是
a[i?1]?a[k]?a[j]
就相當于兩個矩陣相乘的總計算量

所以下標從2開始有意義
例如 3
1 2 3
抽象成矩陣為 1×2 2×3
那么 答案就是 dp[2][n]
左邊起始有意義的點為2 右邊結束點其實就是n
為什么是n呢 因為如果不把n算在內 最終我們循環的
最大的j就是n 如果不考慮n 那么說明我們沒考慮最后一個矩陣的最后一個參數
所以必須要時dp[2][n]
將原序列拆解后的矩陣序列
這道題其實就是相當于考慮剩余首尾兩個元素
其余的全部拿出來的最小代價
注意第n個元素要算到第n-1個的計算量中 所以第n個元素在矩陣問題中就是最后一個參數
這個參數是要合并的

如果全取
我們所要輸出就是dp[1][n+1]了
這個問題之所以可以抽象成矩陣問題
因為我們要提出2-n-1的數 然而在計算的過程中卻把1和n也以a[i?1]?a[k]?a[j]的形式算進去了
也就是能夠表示出矩陣計算量

總結

以上是生活随笔為你收集整理的POJ-1651 Multiplication Puzzle 矩阵连乘问题(区间dp)的全部內容,希望文章能夠幫你解決所遇到的問題。

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