題目鏈結
演算法:劃分型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 ...