• 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

    一个普通的动规+高精

    都是似曾相识的做法

    注定失败的战争,也要拼尽全力去打赢它; 就算输,也要输得足够漂亮。
  • 相关阅读:
    树莓派 无线网卡配置
    树莓派.Net MVC4 Mono4 Jexus
    springcloud超简单的入门3--负载均衡
    springcloud超简单的入门2--Eureka服务治理
    SpringCloud超简单的入门(1)--一些简单的介绍
    Tomcat9控制台中文乱码的解决方案
    win10 调整音量时 左上角弹框 的解决办法
    .NETCore 添加Docker支持,并上传镜像至Docker Hub,最后在CentOs中拉取镜像运行
    假设每台交换机上行有N条线,两跳内,可以最多让多少个交换机互通?
    .netcore微服务-SkyWalking安装部署IIS
  • 原文地址:https://www.cnblogs.com/yalphait/p/9408097.html
Copyright © 2020-2023  润新知