一、心得
1、用excel填陣列很方便
2、dp就是填表
找狀態就是縮小規模
找狀態轉移方程就是 找狀態的最後一次關係
二、題目
總時間限制:
1000ms
記憶體限制:
65536kb
描述今年是國際數學聯盟確定的「2000——世界數學年」,又恰逢我國著名數學家華羅庚先生誕辰90周年。在華羅庚先生的家鄉江蘇金壇,組織了一場別開生面的數學智力競賽的活動,你的乙個好朋友xz也有幸得以參加。活動中,主持人給所有參加活動的選手出了這樣一道題目:
設有乙個長度為n的數字串,要求選手使用k個乘號將它分成k+1個部分,找出一種分法,使得這k+1個部分的乘積能夠為最大。
同時,為了幫助選手能夠正確理解題意,主持人還舉了如下的乙個例子:
有乙個數字串:312,當n=3,k=1時會有以下兩種分法:
1) 3*12=36
2) 31*2=62
這時,符合題目要求的結果是:31*2=62
現在,請你幫助你的好朋友xz設計乙個程式,求得正確的答案。
輸入程式的輸入共有兩行:
第一行共有2個自然數n,k(6≤n≤40,1≤k≤6)
第二行是乙個長度為n的數字串。
輸出輸出所求得的最大乘積(乙個自然數)。(保證最終答案不超過int範圍)
樣例輸入
4 2樣例輸出1231
62**
noip2000複賽 普及組 第三題
三、分析
* 乘積最大
* 狀態:
* f[i][j]表示前j個數字中插入j個乘號
* a[i][j]表示數字串i位置到j位置組成的數的值
* 初始狀態:f[1][0]=a[1][1]
* 最終狀態:f[n][k]
* 狀態轉移方程:
* 預設乘號插在數字之後
* 最後乙個乘號插的位置m的取值範圍為(k,n-1)
* f[i][j]=max(f[m][j-1]*a[m+1][i]) (m>=j&&m<=i-1)
1、求a陣列
2、求dp
四、ac**
1/*2五、注意點* 乘積最大
3* 狀態:
4* f[i][j]表示前j個數字中插入j個乘號
5* a[i][j]表示數字串i位置到j位置組成的數的值
6* 初始狀態:f[1][0]=a[1][1]
7* 最終狀態:f[n][k]
8* 狀態轉移方程:
9* 預設乘號插在數字之後
10* 最後乙個乘號插的位置m的取值範圍為(k,n-1)
11* f[i][j]=max(f[m][j-1]*a[m+1][i]) (m>=j&&m<=i-1)
12*/
1314 #include 15 #include
16using
namespace
std;
17int f[45][10
];18
int a[45][45
];19
intn, k;
20string s; //
數字串21
22void
initarr_a()
26//
根據excel**自己寫,其實很簡單
27for (int i = 1; i <= n; i++) 31}
32}3334
void
printarr_a()
39 cout <
41}4243
void
initarr_f()
48//
水平 f[0][j]
49for (int j = 0; j <= k; j++)
52//
其它部位
53for (int i = 1; i <= n; i++) 57}
58}5960
void
printarr_f()
65 cout <
67}6869
void
init()
7778
void
dp() 84}
85}86//
printarr_f();87}
8889
void
printans()
9293
intmain()
dp 1 跳台階問題
問題 共n層台階,每次只能上1級或者2級,問有多少種上台階的方法。首先分析一下題目,一般這種問題我都會先找一下規模最小的數值來分析一下,可以看到,上一層的走法是1種 1 上2層的走法是2種 11,2 三層有3種 12,21,111 四層有5種 1111,22,211,121,112 偷偷發現好像是斐...
DP1 動態規劃概述
計數求最大值最小值 求存在性 確定狀態 簡單的說,就是解動態規劃時需要開乙個陣列,陣列的每個元素f i 或者f i j 代表什麼,類似解數學題中,xyz代表什麼一樣,具體分為下面兩個步驟 轉移方程 根據子問題定義直接得到 初始條件和邊界情況 初始條件一般都是a 0 a 1 這種,多看看邊界條件主要是...
DP 1 數塔問題
數塔問題 基本模型 如上圖所示數塔,要求從頂層走到底層,若每一步只能走到相鄰的結點,則經過的結點的數字之和最大是多少?數塔思想 自頂向下分析,自底向上計算。h i 表示第i層的最大值。要得到h i 1 則考慮上一層結點,到其相鄰節點可取得的值,取最大值作為h i 1 如果按照上述做法,從頂到底算起,...