原文:https://www.luogu.org/problemnew/solution/P1018?page=7

题目:P1018【乘积最大】


前言:

  • 这题的正解理论上说是DP,可是由于民间数据太水,用暴力过并不难

整体思路:

  1. 利用一个b数组标记每一位之间是否分割(1位分割,0为连接)。
  2. 利用STL里的 next_permutation 求出b的各种排列(即暴力枚举每种情况)。
  3. 由于本题数据规模大,所以要使用高精度计算每种分割的最后结果,并找出最大。

next_permutation函数:

  • 即STL里的求全排列函数,所求的数组必须是升序,否则将无法求出全部的排列方式(这和它生成群排列的方式有关),next_permutation正常和sort一样,有2个参数,分别是数组的首地址和尾地址,并返回一个bool量,即能否求出下一个全排列,可以的话返回true,并将指定数组变为下一个排列方式,如1 2 3的下一个排列方式就是 1 3 2。

上代码:

#include<algorithm> //使用next_permutation需要调用的头文件
#include<cstdio> //c语言读入输出
#include<cstring> //处理高精度字符串时需要用到 using namespace std; struct BigN{ //高精度(即大整数)运算
int num[]={},len;
BigN(char s[]) //构造函数,用于给新定义的大整数赋值
{
len=strlen(s);
for(int i=len-;i>=;i--)
num[i]=s[len-i-]-'';
}
void clean() //用于清零
{
memset(num,,sizeof(num));
}
void f(int n) //将一个普通整数压到大整数的开头,这个在后面分割每一位时会用到
{
for(int i=len;i>;i--)
num[i]=num[i-];
len++;
num[]=n;
}
void cheng(BigN n)//高精度乘法,这里就不过多解释了,有疑问可以前往 P1303 了解更多
{
BigN c("");
int s=,g=;
for(int i=;i<=len;i++)
for(int j=;j<=n.len;j++)
{
int w=i+j;
s=num[i]*n.num[j];
c.num[w]+=s%;
c.num[w+]+=s/+c.num[w]/;
c.num[w]%=;
}
c.len=len+n.len;
while(c.num[c.len]==&&c.len>=)c.len--;
fz(c);
}
void fz(BigN n) //将一个大整数赋值给例外一个大整数,相当于'='
{
len=n.len;
for(int i=;i<=n.len;i++)
num[i]=n.num[i];
}
bool bj(BigN n) //判断两个大整数的大小,用于找出最大结果
{
if(len>n.len)
return ;
else if(len<n.len)
return ;
else
{
for(int i=len;i>=;i--)
if(num[i]<n.num[i])
return ;
else if(num[i]>n.num[i])
return ;
return -;
}
}
void out() //输出
{
for(int i=len;i>=;i--)
printf("%d",num[i]);
}
}; int n,k,sum[],b[],i,j; //常规定义,不多做解释
BigN mmax(""); int main()
{
char s[]; //s用于读入一个大整数
scanf("%d%d%s",&n,&k,&s);
for(i=;i<strlen(s);i++) //在sum中备份一份原数
sum[i]=s[i]-'';
for(i=n-;i>=(n-k)-;i--) //将b数组中的后k个数赋1,因为使用next_permutation需要让数组升序,否则可能无法找出所有排列方式
b[i]=;
do{
BigN temp(""),all("");//temp用于存放分割后的每一节,all用于计算每种排列方式的结果
i=;
while(i<n)//分割
{
if(i!=)
if(b[i-]==)//如果b[i-1]为1,那么就要在这一位加上一个乘号,即将原数分割
all.cheng(temp),temp.clean();//总数乘上分割后的每一位,并将temp清空,用于储存下一节.
temp.f(sum[i]),i++; //将原数的下一位压到temp的最前面
}
all.cheng(temp);//由于temp还没有乘all就退出循环,所以要再乘一次
if(mmax.bj(all)==)//如果这种排列顺序的结果大于之前最大的结果,刷新最大结果
mmax.fz(all);
}while(next_permutation(b,b+n-));//调用next_permutation
mmax.out();//输出
return ;
}

Luogu - P1018 乘积最大 - 题解的更多相关文章

  1. luogu P1018 乘积最大

    题目描述 今年是国际数学联盟确定的"2000――世界数学年",又恰逢我国著名数学家华罗庚先生诞辰90周年.在华罗庚先生的家乡江苏金坛,组织了一场别开生面的数学智力竞赛的活动,你的一 ...

  2. P1018 乘积最大(高精度加/乘)

    P1018 乘积最大 一道dp题目.比较好像的dp题目. 然而他需要高精度计算. 所以,他从我开始学oi,到现在.一直是60分的状态. 今天正打算复习模板.也就有借口解决了这道题目. #include ...

  3. 洛谷 P1018 乘积最大

    P1018 乘积最大 题目描述 今年是国际数学联盟确定的“ 20002000 ――世界数学年”,又恰逢我国著名数学家华罗庚先生诞辰 9090 周年.在华罗庚先生的家乡江苏金坛,组织了一场别开生面的数学 ...

  4. P1018 乘积最大(DP)

    题目 P1018 乘积最大 解析 区间DP 设\(f[i][j]\)表示选\(i\)个数,插入\(j\)个乘号时的最大值 设\(num[i][j]\)是\(s[i,j]\)里的数字 转移方程就是\(f ...

  5. 【luogu P5022 旅行】 题解

    题目连接:https://www.luogu.org/problemnew/show/P5022 \(NOIP2018 DAY2T1\) 考场上只写了60分,很容易想到当 m = n - 1 时的树的 ...

  6. 洛谷P1018乘积最大——区间DP

    题目:https://www.luogu.org/problemnew/show/P1018 区间DP+高精,注意初始化和转移的细节. 代码如下: #include<iostream> # ...

  7. 洛谷—— P1018 乘积最大

    https://www.luogu.org/problem/show?pid=1018#sub 题目描述 今年是国际数学联盟确定的“2000――世界数学年”,又恰逢我国著名数学家华罗庚先生诞辰90周年 ...

  8. P1018 乘积最大

    开始定义状态f[i][j][k]为[i,j)区间插入k个括号,使用记忆化搜索,但是成功爆栈,得到4个mle #include <bits/stdc++.h> using namespace ...

  9. 【luogu P2831 愤怒的小鸟】 题解

    题目链接:https://www.luogu.org/problemnew/show/P2831 写点做题总结:dp,搜索,重在设计状态,状态设的好,转移起来也方便. 对于一条抛物线,三点确定.(0, ...

随机推荐

  1. js点击按钮button效果(波效果)

    Material Design风格纯js按钮点击波特效 演示效果 html部分: <button data-ripple> Demo button 6 </button> cs ...

  2. 2019CISCN web题赛-JustSoSo;love_math(复现)

    0x00前言 这几天从网上找个CMS源码开始练习审计,盯着众多的代码debug调呀调头晕脑胀的,还不错找到个文件读取和一个ssrf... 上月底结束的CISCN线上赛,web四道,仔细研究的2道,做出 ...

  3. sqli-libs笔记Page-1(Basic Challenges)

    0X00:前言 sqli-libs是一个学习SQL注入的开源平台,共有75中不同类型的注入.源码可到github上搜索sqli-libs找到 0X01:Page-1基础挑战 0X02:每一关的payl ...

  4. kubernetes集群内通过endpoint访问外部服务

    kubernetes内的服务访问集群外独立的服务最好通过endpoint方式,例如MySQL 1.创建mysql-service.yaml apiVersion: v1 kind: Service m ...

  5. Kaldi语音识别快速入门

    一.简介 Kaldi是使用C++编写的语音识别工具包,Apache License v2.0许可.主要供语音识别研究人员使用.Kaldi的目标和范围与HTK类似.目标是拥有易于修改和扩展的现代而灵活的 ...

  6. python打印带颜色字体

    设置颜色开始 :\033[显示方式;前景色;背景色m 前景色 背景色 颜色 30 40 黑色 31 41 红色 32 42 绿色 33 43 黃色 34 44 蓝色 35 45 紫红色 36 46 青 ...

  7. VS2015秘钥激活

    点击软件菜单栏的"帮助",点击"注册产品",点击"使用产品密钥解锁",附送产品密钥: 专业版:HMGNV-WCYXV-X7G9W-YCX63 ...

  8. AjAX 异步通信

    <!DOCTYPE html> <html lang="en"> <head> <title>xmlhttprequest ajax ...

  9. 葫芦娃团队对火鸡堂、基于云的胜利冲锋队团队的Beta产品测试报告

    Beta项目互测 课程名称:软件工程1916|W(福州大学) 作业要求:Beta阶段团队项目互评 团队名称:葫芦娃队 作业目标:Beta项目互测 一.火鸡堂团队产品测试 1.截图(推荐用动态gif图录 ...

  10. RF元素定位的例子

    Execute Javascript $("input[type='button']").click() Comment Click Button css=input.login_ ...