ALGO-17_蓝桥杯_算法训练_乘积最大(DP)
问题描述 今年是国际数学联盟确定的“——世界数学年”,又恰逢我国著名数学家华罗庚先生诞辰90周年。在华罗庚先生的家乡江苏金坛,组织了一场别开生面的数学智力竞赛的活动,你的一个好朋友XZ也有幸得以参加。活动中,主持人给所有参加活动的选手出了这样一道题目: 设有一个长度为N的数字串,要求选手使用K个乘号将它分成K+1个部分,找出一种分法,使得这K+1个部分的乘积能够为最大。 同时,为了帮助选手能够正确理解题意,主持人还举了如下的一个例子: 有一个数字串:, 当N=,K=1时会有以下两种分法: *=
*= 这时,符合题目要求的结果是:*= 现在,请你帮助你的好朋友XZ设计一个程序,求得正确的答案。 输入格式 程序的输入共有两行:
第一行共有2个自然数N,K(≤N≤,≤K≤)
第二行是一个长度为N的数字串。 输出格式 输出所求得的最大乘积(一个自然数)。 样例输入
样例输出
记:
由于DP题目的解法仍不熟悉,故上网搜寻解题思路
(代码参考:https://blog.csdn.net/fine_rose/article/details/63685548)
参考代码:
#include <stdio.h>
#define MIN(X,Y) (X)<(Y)?(X):(Y) int n,k;
long long num[] = {};
long long dp[][] = {};/*可使用的数字,*号的个数*/ long long cut(int l,int r)
{
int i;
long long end = ;
for (i = l ; i <= r ;i ++)
{
end = end* + num[i];
}
return end;
} void init()
{
int i;
char tmp[] = {};
scanf("%d %d",&n,&k);
scanf("%s",&tmp);
for (i = ; i <= n ; i ++)
{
num[i] = tmp[i-]-'';
}
for (i = ; i <= n ; i ++)
{
dp[i][] = cut(,i);
}
return ;
} void find()
{
int i,j;
int a,b; for (i = ; i <= n ; i ++)/*枚举能使用数字(1-i),(至少需要2数字才可添加*号)*/
{
j = MIN(i-,k);/*枚举在能使用数字中最多能放的*个数*/
for (a = ; a <= j ; a ++)/*枚举j个乘号情况下的数字分布*/
{
for (b = a ; b < i ; b ++)/*枚举在能使用数字内的不同组合*/
{
if (dp[b][a-]*cut(b+,i) > dp[i][a])
{
dp[i][a] = dp[b][a-]*cut(b+,i);/*存放最大值*/
}
}
}
} return ;
} int main(void)
{
init();
find();
printf("%lld",dp[n][k]);
return ;
}
在过完思路后,可以发现由于会遍历不同长度下的可能结果,而我们仅仅是要长度为n时的最大乘积,显然程序做了大量的无用功
而到这里,思路也有所启发
从题目中,我们可以得到的隐藏条件是n>1,且n>k
而题目的样例输入
4 2
1231
指两个乘号,放在4个数据中间(左右两端不能放),那么
第一个乘号的可能出现位置为:1*2*3*1
第二个乘号的可能出现位置为:12*3*1 (至少已放了一个乘号)
显然,后面的乘号出现位置与前面的乘号的位置有关系,可以通过标记摆放乘号,并用递归遍历不同的乘号(dfs)
这样,我们就可以得到一种情况下的数字分割
通过查乘号的出现位置,完成数字之间的相乘,并比较最大值,将最大值保存
改进代码:
#include <stdio.h>
#define MAX 46 int n,k;
long long num[MAX] = {};/*每一位的数据存储*/
int vis[MAX] = {}; /*每一位乘号的使用标记*/
long long max = ; /*最大值存储*/ void init()
{
int i;
char tmp[MAX] = {};
scanf("%d %d",&n,&k);
scanf("%s",&tmp);
for (i = ; i <= n ; i ++)
{
num[i] = tmp[i-]-'';
}
return ;
} long long cut(int l,int r)
{
int i;
long long end = ;
for (i = l ; i <= r ;i ++)
{
end = end* + num[i];
}
return end;
} void dfs(int x)
{
/*隐藏条件:N>1,N>K*/
int i;
int a,b;/*乘号分割下的数字左右下标*/
long long tmp; if (x > k)/*乘号使用完毕*/
{
a = ,b = ;
tmp = ;
/*计算该次搜索中的数字分割后的乘积*/
for (i = ; i < n ; i ++)
{
if (vis[i])
{
b = i;
tmp *= cut(a+,b);
a = b;
}
}
tmp *= cut(a+,n);
if (tmp > max)
{
max = tmp;
}
return ;
} for (i = x ; i < n ; i ++)/*遍历不同位置的乘号*/
{
if (!vis[i])/*当前位置的乘号未使用*/
{
vis[i] = ;
dfs(x+);
vis[i] = ;
}
} return ;
} int main(void)
{
init();
dfs();
printf("%lld",max);
return ;
}
ALGO-17_蓝桥杯_算法训练_乘积最大(DP)的更多相关文章
- Java实现 蓝桥杯VIP 算法训练 阿尔法乘积
蓝桥杯–阿尔法乘积 问题描述 计算一个整数的阿尔法乘积.对于一个整数x来说,它的阿尔法乘积是这样来计算的:如果x是一个个位数,那么它的阿尔法乘积就是它本身:否则的话,x的阿尔法乘积就等于它的各位非0的 ...
- [蓝桥杯]ALGO-20.算法训练_求先序排列
问题描述 给出一棵二叉树的中序与后序排列.求出它的先序排列.(约定树结点用不同的大写字母表示,长度<=). 输入格式 两行,每行一个字符串,分别表示中序和后序排列 输出格式 一个字符串,表示所求 ...
- [蓝桥杯]ALGO-16.算法训练_进制转换
问题描述 我们可以用这样的方式来表示一个十进制数: 将每个阿拉伯数字乘以一个以该数字所处位置的(值减1)为指数,以10为底数的幂之和的形式.例如:123可表示为 1*102+2*101+3*100这样 ...
- [蓝桥杯]ALGO-15.算法训练_旅行家的预算
问题描述 一个旅行家想驾驶汽车以最少的费用从一个城市到另一个城市(假设出发时油箱是空的).给定两个城市之间的距离D1.汽车油箱的容量C(以升为单位).每升汽油能行驶的距离D2.出发点每升汽油价格P和沿 ...
- [蓝桥杯]ALGO-124.算法训练_数字三角形
问题描述 (图3.1-1)示出了一个数字三角形. 请编一个程序计算从顶至底的某处的一条路 径,使该路径所经过的数字的总和最大. ●每一步可沿左斜线向下或右斜线向下走: ●<三角形行数≤: ●三角 ...
- [蓝桥杯]ALGO-122.算法训练_未名湖边的烦恼
问题描述 每年冬天,北大未名湖上都是滑冰的好地方.北大体育组准备了许多冰鞋,可是人太多了,每天下午收工后,常常一双冰鞋都不剩. 每天早上,租鞋窗口都会排起长龙,假设有还鞋的m个,有需要租鞋的n个.现在 ...
- [蓝桥杯]ALGO-116.算法训练_最大的算式
问题描述 题目很简单,给出N个数字,不改变它们的相对位置,在中间加入K个乘号和N-K-1个加号,(括号随便加)使最终结果尽量大.因为乘号和加号一共就是N-1个了,所以恰好每两个相邻数字之间都有一个符号 ...
- [蓝桥杯]ALGO-101.算法训练_图形显示
问题描述 编写一个程序,首先输入一个整数,例如5,然后在屏幕上显示如下的图形(5表示行数): * * * * * * * * * * * * * * * 题目描述 代码如下: #include < ...
- [蓝桥杯]ALGO-97.算法训练_排序
题目描述: 问题描述 编写一个程序,输入3个整数,然后程序将对这三个整数按照从大到小进行排列. 输入格式:输入只有一行,即三个整数,中间用空格隔开. 输出格式:输出只有一行,即排序后的结果. 输入输出 ...
- [蓝桥杯]ALGO-92.算法训练_前缀表达式
问题描述 编写一个程序,以字符串方式输入一个前缀表达式,然后计算它的值.输入格式为:“运算符 对象1 对象2”,其中,运算符为“+”(加法).“-”(减法).“*”(乘法)或“/”(除法),运算对象为 ...
随机推荐
- 举例说明MySQL中的事务
一.场景导入 现在有一张仓库表,仓库表中记录了每一个物品的数量,还有一张用户表,用户购买产品,仓库表的产品数量减少,而用户拥有产品的数量增加. 但是如果仓库中的产品数量不足时怎么处理? 例子: #仓库 ...
- 第一次Scrum会议(10/13)【欢迎来怼】
一.小组信息 队名:欢迎来怼 小组成员 队长:田继平 成员:李圆圆,葛美义,王伟东,姜珊,邵朔,冉华 小组照片 二.开会信息 时间:2017/10/13 16:22~16:47,总计25min. 地点 ...
- this语句的用法第一、二点
1.this是js的一个关键字,指定一个对象然后去代替他. 函数内的this和函数外的this,函数内的this指向行为发生的主体.函数外的this都指向window没有意思. 例题: functio ...
- 2018.4.23 《深入理解Java虚拟机:JVM高级特性与最佳实践》笔记
一.Java内存区域与内存溢出 1.程序计数器是一块较小的内存空间,它可看作是当前线程所执行的字节码的行号指示器.字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令.各条线程 ...
- EasyUI datagrid 一个可以 直接运行例子一个文件 六
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta ht ...
- stack 的一些用法
#include<bits/stdc++.h> using namespace std; int32_t main() { stack<int> st; st.push(); ...
- canvas的认识,时钟的设置
canvas的三要素:ID标识,width宽度,height高度,他是行元素 IE9才支持canvas,canvas是一个透明的画板,要用js去画 绘制一个圆 线性渐变颜色 径向渐变 图片的绘制: 视 ...
- Go Example--闭包
package main import "fmt" func main() { //这里需要将闭包函数当作一个类理解,这里是实例化 nextInt := intSeq() fmt. ...
- LeetCode – First Missing Positive
Given an unsorted integer array, find the smallest missing positive integer. Example 1: Input: [1,2, ...
- IntelliJ IDEA备忘
IntelliJ IDEA生成get/set方法的快捷键 IntelliJ IDEA生成get/set有2种方式,alt+enter.alt+insert.下面分别介绍这2种方式快速生成get与set ...