划分型动态规划 之 CODE[VS] 1017 乘积最大 2000年NOIP全国联赛提高组
/*
dp[i][k] := 截取并获得原字符串前面长度为i+1的字符串,使用K个乘号将它分成K+1个部分,这K+1个部分的乘积的最大值
初始化:
dp[][] = { 0 }
dp[i][0] = Num(0, i); // 截取并获得原字符串前面长度为(i+1)的字符串(字符串0~i位置),返回其所对应的数值
状态方程:
dp[i][k] = max(dp[i][k], dp[j][k-1]*Num(j+1, i))
0<=j<i
答案:
dp[N-1][K]
*/
1 #define _CRTDBG_MAP_ALLOC 2 #include <stdlib.h> 3 #include <crtdbg.h> 4 #define _CRT_SECURE_NO_WARNINGS 5 #define HOME 6 7 #include <iostream> 8 #include <cstdlib> 9 #include <cstdio> 10 #include <cstddef> 11 #include <iterator> 12 #include <algorithm> 13 #include <string> 14 #include <locale> 15 #include <cmath> 16 #include <vector> 17 #include <cstring> 18 using namespace std; 19 const int INF = 0x3f3f3f3f; 20 const int MaxN = 45; 21 const int MaxK = 10; 22 23 24 int N, K; 25 string numStr; 26 int dp[MaxN][MaxK] = { 0 }; 27 28 29 int Num(int ibegin, int iend) 30 { 31 int num = 0; 32 int tenMul = 1; 33 for (int i = iend; i >= ibegin; --i) 34 { 35 num += ((numStr[i] - '0') * tenMul); 36 tenMul *= 10; 37 } 38 return num; 39 } 40 41 void Solve() 42 { 43 for (int i = 0; i < N; ++i) 44 { 45 for (int j = 0; j < i; ++j) 46 { 47 for (int k = 1; k <= K; ++k) 48 { 49 //printf("%d -> %d : %d\n", j+1, i, Num(j + 1, i)); 50 dp[i][k] = max(dp[i][k], dp[j][k - 1] * Num(j + 1, i)); 51 //printf(" %d -> %d : %d\n", j, k-1, dp[j][k-1]); 52 //printf(" %d -> %d : %d\n", i, k, dp[i][k]); 53 } 54 } 55 } 56 cout << dp[N - 1][K] << endl; 57 } 58 59 int main() 60 { 61 #ifdef HOME 62 freopen("in", "r", stdin); 63 //freopen("out", "w", stdout); 64 #endif 65 66 cin >> N >> K; 67 cin >> numStr; 68 for (int i = 0; i < N; ++i) 69 { 70 dp[i][0] = Num(0, i); 71 } 72 Solve(); 73 74 #ifdef HOME 75 cerr << "Time elapsed: " << clock() / CLOCKS_PER_SEC << " ms" << endl; 76 _CrtDumpMemoryLeaks(); 77 system("pause"); 78 #endif 79 return 0; 80 }