国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

POJ1651 Multiplication Puzzle(DP矩陣鏈)

2019-11-14 13:00:33
字體:
來源:轉載
供稿:網友

Multiplication Puzzle Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9500 Accepted: 5906 Description

The multiplication puzzle is played with a row of cards, each containing a single positive integer. During the move player takes one card out of the row and scores the number of points equal to the PRoduct of the number on the card taken and the numbers on the cards on the left and on the right of it. It is not allowed to take out the first and the last card in the row. After the final move, only two cards are left in the row.

The goal is to take cards in such order as to minimize the total number of scored points.

For example, if cards in the row contain numbers 10 1 50 20 5, player might take a card with 1, then 20 and 50, scoring 10*1*50 + 50*20*5 + 10*50*5 = 500+5000+2500 = 8000

If he would take the cards in the opposite order, i.e. 50, then 20, then 1, the score would be 1*50*20 + 1*20*5 + 10*1*5 = 1000+100+50 = 1150. Input

The first line of the input contains the number of cards N (3 <= N <= 100). The second line contains N integers in the range from 1 to 100, separated by spaces. Output

Output must contain a single integer - the minimal score. Sample Input

6 10 1 50 50 20 5 Sample Output

3650

分析 矩陣鏈(Matrix Chain),用迭代實現動態規劃. 我把分析放在了代碼注釋中

感受 剛開始一直看別人代碼,看不懂后來拿紙一步一步算總算弄明白了,Orz看十遍不如親手算一遍.

#include<cstdio>#include<iostream>#include<algorithm>#include<cmath> #include<vector>using namespace std;#define inf 0x3fffffff#define maxn 105int p[maxn];// 表示矩陣的行數, 注意我是從0開始的 int m[maxn][maxn];//m[i][j]表示從第i個矩陣鏈到第j個矩陣鏈的最少相乘次數 int s[maxn][maxn];//s[i][j]表示從第i個矩陣鏈到第j個矩陣鏈的分界點(也就是解的追蹤),在本題中可以不寫 void matrix_chain(int* p,int n,int m[maxn][maxn],int s[maxn][maxn]){ for(int i=0;i<=n;i++) m[i][i]=0; for(int len=2;len<n;len++)//len:鏈長 for(int i=1;i<=n-len+1;i++)// i:左邊界 (i=1,表示第i個矩陣鏈) { int j=i+len-1;//通過左邊界i和鏈長r可確定右邊界j (j:第j個矩陣鏈) m[i][j]=inf;// init for(int k=i;k<=j-1;k++){ int t=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j]; if( t < m[i][j]){ m[i][j]=t; //更新解 s[i][j]=k; } } } }//print_parens的功能是打印括弧,本題可以不要. //paren : 括弧//感覺和線段樹有點相似,對著樣例把這個樹畫出來就懂了,圖在代碼的最下面*/ void print_parens(int s[maxn][maxn],int i ,int j) { if(i==j) printf("A%d",i); else { printf("("); print_parens(s,i,s[i][j]); print_parens(s,s[i][j]+1,j);//遞歸調用 printf(")"); } } int main(){ //freopen("in.txt","r",stdin); int n; scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%d",&p[i]); } matrix_chain(p,n,m,s); printf("%d/n",m[1][n-1]); /* printf("%d/n",s[1][n-1]); printf("%d/n",s[2][n-1]); printf("%d/n",s[2][4]); printf("/nprint_parens:/n"); print_parens(s,1,n-1); */ return 0; }

關于print_parens的理解 下圖是依據樣例可以畫出的樹,然后按照先序遍歷訪問所有節點. 這里寫圖片描述 對于綠色節點: 第一次訪問打印左括弧(即入棧時打印“(”) ,第二次訪問打印右括弧(即出棧時打印”)”) 對于紅色節點: 直接輸出Ai

最后打印出的結果為: (A1(((A2A3)A4)A5))


上一篇:1013_開門人和關門人

下一篇:HDU 6012

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 沂源县| 库车县| 岐山县| 江永县| 乌海市| 望城县| 汤阴县| 香港| 嘉兴市| 滨海县| 裕民县| 阳东县| 伊春市| 津市市| 乡宁县| 渑池县| 潮安县| 松滋市| 汕尾市| 和静县| 南雄市| 黄石市| 驻马店市| 长顺县| 清新县| 淳安县| 临武县| 建昌县| 兴文县| 理塘县| 五台县| 红原县| 漳州市| 伊宁县| 即墨市| 宜宾县| 冷水江市| 龙泉市| 密云县| 萍乡市| 平潭县|