一本通 1275:【例9.19】乘積最大
【題目描述】
今年是國際數學聯盟確定的「2000——世界數學年」,又恰逢我國著名數學家華羅庚先生誕辰90周年。在華羅庚先生的家鄉江蘇金壇,組織了一場別開生面的數學智力競賽的活動,你的乙個好朋友xz也有幸得以參加。活動中,主持人給所有參加活動的選手出了這樣一道題目:
設有乙個長度為n的數字串,要求選手使用k個乘號將它分成k+1個部分,找出一種分法,使得這k+1個部分的乘積最大。
同時,為了幫助選手能夠正確理解題意,主持人還舉了如下的乙個例子:
有乙個數字串:312, 當n=3,k=1時會有以下兩種分法:
1)312=36
2)312=62
這時,符合題目要求的結果是:31*2=62。
現在,請你幫助你的好朋友xz設計乙個程式,求得正確的答案。
【輸入】
第一行共有2個自然數n,k(6≤n≤10,1≤k≤6)
第二行是乙個長度為n的數字串。
【輸出】
輸出所求得的最大乘積(乙個自然數)。
【輸入樣例】
4 21231
【輸出樣例】
62思路:
本道題是一道區間dp問題,而且對階段數有限制 k。可以將其按照插入乘號數來進行劃分。如果插入k個乘號,可以把問題看做k個階段的決策問題。
1、然要用乙個陣列用來記錄組成結果的值,在合併石子中是前i堆石子的個數,在本道題中,是數字的大小,也就是用a[j][i]表示從第j位到第i位所組成的自然數。
2、用f[j][k] 儲存階段k的每乙個狀態,表示前 j 位的數字用 k 個乘號能夠得到的最大的結果(劃分成小問題)
3、邊界條件,f[j][0] 當k=0 時,表示沒有乘號,則f[j][0] 就是前 j 位組成的數字 f[j][0] = a[1][j]。
注意:還是階段、狀態、決策三層迴圈。
在考慮加乙個乘號的時候要考慮這個乘號應該放在當前面有k-1的乘號時,後面的哪個位置比較好。也就是說要確定前j位用k個乘號f[i][k](j>=k+1)的結果,應該從 有k-1個乘號的各種方案(前幾位中已經包括了k-1個乘號)中選擇哪種方案將第k個乘號加在後面之後結果最大。
要明白有k個乘號時,數字至少要有k+1位。有k-1個乘號時,數字至少要有k位。
狀態轉移方程:f[i][k] = max ( f[i][k], f[j][k-1] * a[j+1][i] )(j < i)
核心**:
for
(int kl=
1;kl<=k;kl++
)}
本題**:
在這裡插入**片
#include
#include
#include
#include
using
namespace std;
//仍然要用乙個陣列用來記錄組成結果的值,在合併石子中是前i堆石子的個數
//在本道題中,是數字的大小,也就是用a[j][i]表示從第j位到第i位所組成的自然數
//k個階段的決策問題
intmain()
}//檢測
/*for(int j=1;jlong
long
int f[11]
[7];
//f[i][k]表示在前i位數中插入k個乘號所得到的的最大值
for(
int i=
0;i<=
10;i++
)//初始化 因為是乘積 所以先初始化為1
for(
int j=
0;j<=
6;j++
) f[i]
[j]=1;
for(
int j=
1;j<=n;j++
)//初始化
f[j][0
]=a[1]
[j];
//邊界條件 當沒有乘號的時候,結果值就是數值
//過程
for(
int kl=
1;kl<=k;kl++)}
cout<[k]
}
乘積最大 區間型dp
題目描述 description 今年是國際數學聯盟確定的 2000 世界數學年 又恰逢我國著名數學家華羅庚先生誕辰90周年。在華羅庚先生的家鄉江蘇金壇,組織了一場別開生面的數學智力競賽的活動,你的乙個好朋友xz也有幸得以參加。活動中,主持人給所有參加活動的選手出了這樣一道題目 設有乙個長度為n的數...
1275 例9 19 乘積最大 區間dp
1275 例9.19 乘積最大 時間限制 1000 ms 記憶體限制 65536 kb 提交數 3868 通過數 2568 題目描述 今年是國際數學聯盟確定的 2000 世界數學年 又恰逢我國著名數學家華羅庚先生誕辰90周年。在華羅庚先生的家鄉江蘇金壇,組織了一場別開生面的數學智力競賽的活動,你的乙...
洛谷 P1018 乘積最大(區間DP)
題目大意 有一串數字,我們要求出怎麼在裡面插入乘號,可以使得總乘積最大。解題思路 暴力不可行,這裡我們用區間dp,所謂的區間dp就是狀態裡面包含有區間的端點,然後不斷推。這裡的轉移方程為 for i l n 1 dp l k max dp l k dp i 1 k 1 no 其中,dp l k 表示...