wikioi 1017 乘積最大

2021-09-06 13:19:49 字數 1303 閱讀 5864

題目鏈結

演算法:劃分型dp

非常典型的一道題目,劃分型dp

題目描述:

設有乙個長度為n的數字串,要求選手使用k個乘號將它分成k+1個部分,找出一種分法,使得這k+1個部分的乘積能夠為最大。同時,為了幫助選手能夠正確理解題意,主持人還舉了如下的乙個例子:有乙個數字串:312, 當n=3,k=1時會有以下兩種分法:

1)  3*12=36

2)  31*2=62

這時,符合題目要求的結果是:31*2=62現在,請你幫助你的好朋友xz設計乙個程式,求得正確的答案。

設數字串為a1a2a3……an。當k=1時,最大值為

max當k=2時,最大值為

max引入記號f[i,k]表示從a0到ai,插入k個乘號所取得的最大值,用c[i,j]表示從ai到aj的數字列,則:

k=1時

f[n,1]=max

k=2時

f[n,2]=max

所以匯出

f[n,k]=max

我們用f[n][k]來表示f[n,k],表示劃分k次得到的數最大,用a[i][j]表示c[i,j]

得到:f[i][1] = max(f[i][1], a[1][j]*a[j+1][i])  (1 <= j < i)

f[i][k] = max(f[i][k], a[j+1][i]*f[j][k-1]) (k <= j < i)

其實這裡可以簡化成:

f[i][0] = a[1][i]  (1 <= i <= n)

f[i][k] = max(f[i][k], a[j+1][i]*f[j][k-1]) (k <= j < i, 1 <= k <= m) m是要新增的乘號數目

而且發現,方程是以劃分次數k為階段,且順序是遞增(從k到i列舉j即可),那麼我們就自底向上的來遞推

所以順序就一木了然了

上**:

#include #include #include using namespace std;

int n, m, i, j, k;

const int maxk = 10;

const int maxn = 100;

int c[maxn] = , a[maxn][maxn] = }, f[maxn][maxk] = };

int makeconut(int x, int y) //求x到y之間的數字列

int main()

1017 乘積最大

題目描述 description 今年是國際數學聯盟確定的 2000 世界數學年 又恰逢我國著名數學家華羅庚先生誕辰90周年。在華羅庚先生的家鄉江蘇金壇,組織了一場別開生面的數學智力競賽的活動,你的乙個好朋友xz也有幸得以參加。活動中,主持人給所有參加活動的選手出了這樣一道題目 設有乙個長度為n的數...

1017 乘積最大

題目描述 description 今年是國際數學聯盟確定的 2000 世界數學年 又恰逢我國著名數學家華羅庚先生誕辰90周年。在華羅庚先生的家鄉江蘇金壇,組織了一場別開生面的數學智力競賽的活動,你的乙個好朋友xz也有幸得以參加。活動中,主持人給所有參加活動的選手出了這樣一道題目 設有乙個長度為n的數...

CODE VS 1017 乘積最大

題目 思路 將n個字元分割為k個數並相乘,可劃分為m個字元組成的數,乘以將n m的字元分割為k 1個數。題解 1017 乘積最大 include define debug define toint x x 0 將字元轉換為整型 define maxn 41 最大字串長度 define maxk 7 ...