u011 乘法難題

2022-09-14 18:24:14 字數 1243 閱讀 1303

time limit: 1 second

memory limit: 128 mb

乘法難題是一種用一行的卡片來玩的單人遊戲,每張卡片上有乙個正整數。在遊戲者從中拿出一卡片,並且得到乙個分數,它等於被拿走的卡片上的數與這張卡片左右兩張卡片上的整數的積。第一張與與最後一張卡片不能被拿出。在最後一次移動後,這行卡片中只剩下兩張。 你的目標是怎樣確定拿卡片的順序,以使得總分數的值最小。例如,有一行的卡片,它上面的數字為10 1 50 20 5, 遊戲者可以先取走1這張卡片,然後是20 和50,總分數為10*1*50

+ 50*20*5 + 10*50*5 = 500+5000+2500 = 8000,如果他先拿50, 然接著20,最後取出1, 總分數為1*50*20 + 1*20*5 + 10*1*5 = 1000+100+50 = 1150。

輸入檔案的第一行包含卡片的總數n(3 <= n <= 100),第二行包含n個範圍在1到100之間的整數(兩個整數之間有乙個空格)

輸出檔案包含乙個整數,為最少的分數。

6

10 1 50 50 20 5

3650
【題解】

設f[i][j]表示從i到j,除了i和j之外都被取走所能得到的最小分數。

f[i][j] = min(f[i][k]+f[k][j]+a[i]*a[k]*a[j]); i

初值:f[i][i+1] == 0;

更新方式如下:

for (int l=2;l<= n;l++)

for (int s = 1;s <= n-l;s++)

最後答案為f[1][n];

這裡一定要先列舉這段的長度。

這樣我們可以先獲得像f[1][3],f[2][4],f[3][5]..f[n-2][n]這樣的值。

然後我們在求f[1][4]的時候k在2..3列舉

f[1][4] = min(f[1][2]+f[2][4]+a[1]*a[2]*a[4],f[1][3]+f[3][4]+a[1]*a[3]*a[4]);

可以看到我們在求f[1][4]的時候要用到的f[2][4],f[1][3]都已經求出來了 。

這是原因所在。

也是這種型別動規的原理->不斷利用小的區間擴大區間。

【**】

#include #include int a[101],n,f[101][101];

int main()

} printf("%d\n", f[1][n]);

return 0;

}