1. 程式人生 > >dp練習(9)——最大乘積

dp練習(9)——最大乘積

flask 在屏幕上 黃金 輸出 scrip ext using 兩種 memset

1017 乘積最大

2000年NOIP全國聯賽普及組NOIP全國聯賽提高組

時間限制: 1 s 空間限制: 128000 KB 題目等級 : 黃金 Gold 題目描述 Description

今年是國際數學聯盟確定的“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設計一個程序,求得正確的答案。

輸入描述 Input Description

程序的輸入共有兩行:

第一行共有2個自然數N,K(6≤N≤40,1≤K≤6)

第二行是一個長度為N的數字串。

輸出描述 Output Description

結果顯示在屏幕上,相對於輸入,應輸出所求得的最大乘積(一個自然數)。

樣例輸入 Sample Input

4 2

1231

樣例輸出 Sample Output

62

數據範圍及提示 Data Size & Hint

本題由於比較老,數據實際也比較小,用long long 即可通過

#include<bits/stdc++.h>
using namespace std;

long long dp[1005][1005];
char s[1005];

long long SUM(int j,int i)
{
    long long sum = 0;
    for(int t=j-1;t < i;t++)
    {
        sum 
= sum * 10 + (s[t] - 0); } return sum; } int main() { int n,k; cin >> n >> k; cin >> s; memset(dp,0, sizeof(dp)); for(int i=1;i <= n;i++) { dp[i][0] = SUM(1,i); // cout << dp[i][0] << endl; } for(int h=1;h <= k;h++) { for(int i=1;i <= n;i++) { for(int j=1;j <= i;j++) { dp[i][h] = max(dp[i][h],dp[j][h-1] * SUM(j+1,i)); } } } // for(int i=0;i < 5;i++) // { // for(int j=0;j < 5;j++) // cout << dp[i][j] << " "; // cout << endl; // } cout << dp[n][k] << endl; return 0; }

隔了一天重寫一遍,寫的倒是很快,基本都是背出來的,不是自己想出來的,還是要加深理解,不要當一個模板戰士。

dp練習(9)——最大乘積