18.08.02 luogu P1018 乘积最大

题目描述

今年是国际数学联盟确定的“ 2000 ――世界数学年”,又恰逢我国著名数学家华罗庚先生诞辰 9090 周年。在华罗庚先生的家乡江苏金坛,组织了一场别开生面的数学智力竞赛的活动,你的一个好朋友 XZ 也有幸得以参加。活动中,主持人给所有参加活动的选手出了这样一道题目:

设有一个长度为 N 的数字串,要求选手使用 K 个乘号将它分成 K+1 个部分,找出一种分法,使得这 K+1个部分的乘积能够为最大。

同时,为了帮助选手能够正确理解题意,主持人还举了如下的一个例子:

有一个数字串: 312, 当 N=3,K=1时会有以下两种分法:

1、 63×12=36
2、 31×2=62

这时,符合题目要求的结果是: 31×2=62

现在,请你帮助你的好朋友 XZ 设计一个程序,求得正确的答案。

输入输出格式

输入格式:

 

程序的输入共有两行:

第一行共有 2 个自然数 N,K ( 6N40,1K6 )

第二行是一个长度为 N 的数字串。

 

输出格式:

 

结果显示在屏幕上,相对于输入,应输出所求得的最大乘积(一个自然数)。

 

输入输出样例

输入样例#1: 
4  2
1231
输出样例#1: 
62

说明

NOIp2000提高组第二题

 1 #include<iostream>
 2 #include<cstdlib>
 3 #include<cstdio>
 4 #include <string>
 5 #include <cstring>
 6 #include <algorithm>
 7 #include<map>
 8 #include <math.h>
 9 using namespace std;
10 
11 int len, mul;
12 int num[50];
13 struct node {
14     int num[200];
15     node() { memset(num, 0, sizeof(num)); }
16     node(int *p1, int *p2) {
17         int i = 0;
18         int tmp[50];
19         memset(num, 0, sizeof(num));
20         for (; p1 + i != p2; i++)
21             tmp[i+1] = *(p1 + i);
22         for (int j = 1; j <= i; j++)
23             num[j] = tmp[i + 1 - j];
24         num[0] = i ;
25     }
26     node operator *(node x) {
27         node ans;
28         for (int i = 1; i <= num[0]; i++)
29             for (int j = 1; j <= x.num[0]; j++) {
30                 ans.num[i + j - 1] += num[i] * x.num[j];
31                 ans.num[i + j] += ans.num[i + j - 1] / 10;
32                 ans.num[i + j - 1] %= 10;
33                 ans.num[0] = max(ans.num[0], i + j - 1);
34                 if (ans.num[i + j] != 0)
35                     ans.num[0] = max(ans.num[0], i + j);
36             }
37         return ans;
38     }
39     void print() {
40         for (int i = num[0]; i >= 1; i--)
41             printf("%d", num[i]);
42         printf("
");
43     }
44 };
45 bool operator<(node p,node x) {
46     if (p.num[0] < x.num[0])
47         return true;
48     if (p.num[0] > x.num[0])
49         return false;
50     for (int i = p.num[0]; i >= 1; i--)
51     {
52         if (p.num[i] < x.num[i])
53             return true;
54         if (p.num[i] > x.num[i])
55             return false;
56     }
57     return false;
58 }
59 node f[50][10];
60 
61 void dp() {
62     for(int i=1;i<=mul;i++)
63         for (int j = i + 1; j <= len; j++) {
64             for (int k = i; k < j; k++) 
65                 f[j][i] = max(f[k][i - 1] * node(num + k + 1, num + j + 1), f[j][i]);
66         }
67 }
68 
69 int main()
70 {
71     scanf("%d%d", &len, &mul);
72     char n[50];
73     cin >> n;
74     for (int i = 1; i <= len; i++)
75     {
76         num[i] = n[i-1] - '0';
77         f[i][0] = node(num + 1, num + i + 1);
78     }
79     dp();
80     f[len][mul].print();
81     return 0;
82 }
View Code

一个普通的动规+高精

都是似曾相识的做法

注定失败的战争,也要拼尽全力去打赢它; 就算输,也要输得足够漂亮。
原文地址:https://www.cnblogs.com/yalphait/p/9408097.html