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

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

POJ1651 Multiplication Puzzle(DP矩陣鏈)

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

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))


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 福安市| 崇文区| 延吉市| 肇东市| 伽师县| 理塘县| 霞浦县| 瑞安市| 阿拉善右旗| 遂溪县| 嘉荫县| 兴义市| 南和县| 井冈山市| 达州市| 富民县| 庆阳市| 稷山县| 崇礼县| 务川| 贺兰县| 丽江市| 郧西县| 舒城县| 乌鲁木齐市| 正定县| 仲巴县| 明光市| 上犹县| 托克托县| 仁怀市| 布尔津县| 探索| 云林县| 桦川县| 门源| 夏津县| 宜昌市| 五家渠市| 谷城县| 德昌县|