您的位置:首页 > 其它

划分型动态规划 之 CODE[VS] 1017 乘积最大 2000年NOIP全国联赛提高组

2015-11-13 22:33 393 查看
/*
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]
*/


#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#define _CRT_SECURE_NO_WARNINGS
#define HOME

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstddef>
#include <iterator>
#include <algorithm>
#include <string>
#include <locale>
#include <cmath>
#include <vector>
#include <cstring>
using namespace std;
const int INF = 0x3f3f3f3f;
const int MaxN = 45;
const int MaxK = 10;

int N, K;
string numStr;
int dp[MaxN][MaxK] = { 0 };

int Num(int ibegin, int iend)
{
int num = 0;
int tenMul = 1;
for (int i = iend; i >= ibegin; --i)
{
num += ((numStr[i] - '0') * tenMul);
tenMul *= 10;
}
return num;
}

void Solve()
{
for (int i = 0; i < N; ++i)
{
for (int j = 0; j < i; ++j)
{
for (int k = 1; k <= K; ++k)
{
//printf("%d -> %d : %d\n", j+1, i, Num(j + 1, i));
dp[i][k] = max(dp[i][k], dp[j][k - 1] * Num(j + 1, i));
//printf("    %d -> %d : %d\n", j, k-1, dp[j][k-1]);
//printf("    %d -> %d : %d\n", i, k, dp[i][k]);
}
}
}
cout << dp[N - 1][K] << endl;
}

int main()
{
#ifdef HOME
freopen("in", "r", stdin);
//freopen("out", "w", stdout);
#endif

cin >> N >> K;
cin >> numStr;
for (int i = 0; i < N; ++i)
{
dp[i][0] = Num(0, i);
}
Solve();

#ifdef HOME
cerr << "Time elapsed: " << clock() / CLOCKS_PER_SEC << " ms" << endl;
_CrtDumpMemoryLeaks();
system("pause");
#endif
return 0;
}





                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: