题目大意:

如何把一个正整数N(N长度<20)划分为M(M>=1)个部分,使这M个部分的乘积最大。N、M从键盘输入,输出最大值及一种划分方式。

输入格式:

第一行一个正整数T(T<=10000),表示有T组数据。

接下来T行每行两个正整数N,M。

输出格式

对于每组数据

第一行输出最大值。

第二行输出划分方案,将N按顺序分成M个数输出,两个数之间用空格格开。

算法分析:

第一问求dp值就是简单的dp 具体实现可参见 暑假集训day1 水题 乘法最大

1.做第一问的时候注意这个题给出的M并不是乘号数量而是分成的份数,所以读入M之后记得M-1,到后面便历乘号数量j的时候也是min(i-1,m)。

2.记录路径的方法也跟平时记录路径一样,如果更改了dp的值说明在这个位置插入了乘号,就让path[i][j] = k(k记录断点,i记录前i个数字,j表示共有j个乘号)

3.最后递归输出就可以了,递归函数传参x为当前为前x个数字,t表示还有t个乘号没有插入

(注意一个细节,递归边界是t=-1而不是t=0,因为t等于0的时候表示的是有0个乘号但是仍然是分成一份,即仍然有值,只有当t遍历到-1的时候才说明没有东西可以递归了)

代码展示

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e3+10;
int a[maxn],n,T,path[maxn][maxn],m;
long long dp[maxn][maxn],sum[maxn][maxn];
char s[maxn]; void clear(){
n = strlen(s+1);
memset(sum,0,sizeof(sum));
memset(dp,0,sizeof(dp));
for(int i = 1;i <= n;++i)
for(int j = i;j <= n;++j)
sum[i][j] = sum[i][j-1]*10 + s[j] - '0';
for(int i = 1;i <= n;++i)dp[i][0] = sum[1][i];
return ;
} void Path(int x,int t){
if(t == -1)return;
Path(path[x][t],t-1);
printf("%lld ",sum[path[x][t]+1][x]);
} int main(){
scanf("%d",&T);
while(T--){
scanf("%s %d",s+1,&m);m--;
clear();
for(int i = 1;i <= n;++i){
for(int j = 1;j <= min(i-1,m);++j)
for(int k = 1;k < i;++k){
if(dp[i][j] < dp[k][j-1]*sum[k+1][i]){
dp[i][j] = dp[k][j-1]*sum[k+1][i];
path[i][j] = k;
}
}
}
printf("%lld\n",dp[n][m]);
Path(n,m);
printf("\n");
}
return 0;
}

制作不易,关注走起>)<

暑假集训Day1 整数划分的更多相关文章

  1. 暑假集训day1 水题 乘法最大

    题目大意:有一个长度为N的字符串,要求用K个乘号将其分成K+1个部分,求各个部分相乘的最大值 输入:第一行输入N和K,第二行输入一个长度为N的字符串 算法分析 1. 这个题只是一个简单的dp(甚至连区 ...

  2. 整数划分 (区间DP)

    整数划分(四) 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 暑假来了,hrdv 又要留学校在参加ACM集训了,集训的生活非常Happy(ps:你懂得),可是他最近 ...

  3. 2015UESTC 暑假集训总结

    day1: 考微观经济学去了…… day2: 一开始就看了看一道题目最短的B题,拍了半小时交了上去wa了 感觉自己一定是自己想错了,于是去拍大家都过的A题,十分钟拍完交上去就A了 然后B题写了一发暴力 ...

  4. ACM 整数划分(四)

    整数划分(四) 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 暑假来了,hrdv 又要留学校在参加ACM集训了,集训的生活非常Happy(ps:你懂得),可是他最近 ...

  5. 【欧拉回路+最小生成树】SD开车@山东2018省队一轮集训day1

    目录 [欧拉回路+最小生成树]SD开车@山东2018省队一轮集训day1 PROBLEM 题目描述 输入 输出 样例输入 样例输出 提示 SOLUTION CODE [欧拉回路+最小生成树]SD开车@ ...

  6. 考前停课集训 Day1 废

    [友情链接] Day1 今天模拟赛倒数…… 感觉自己菜到爆炸…… 被一个以前初一的倒数爆踩…… 感觉自己白学了. 满分400,自己只有100.真的是倒数第一…… 做了一个T2,其他暴力分全部没有拿到… ...

  7. nyoj746 整数划分(四)

    整数划分(四) 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 暑假来了,hrdv 又要留学校在参加ACM集训了,集训的生活非常Happy(ps:你懂得),可是他最近遇到 ...

  8. 「疫期集训day1」无言

    正式集训第一天,感觉没啥特别大的感受,无非是奥赛时间延长了,效率提高了,身外事少了 当然不止这些 感受1:有些曾经被恶的题现在仍然在恶心,例如昨天的farmcraft,今天的整数划分(和着多边形一块调 ...

  9. NYOJ746——整数划分(四)

    描述 暑假来了,hrdv 又要留学校在参加ACM集训了,集训的生活非常Happy(ps:你懂得),可是他最近遇到了一个难题,让他百思不得其解,他非常郁闷..亲爱的你能帮帮他吗? 问题是我们经常见到的整 ...

随机推荐

  1. rewrite和return的简单需求

    Rewrite 需求作业 背景:现在我有一个网站,www.linux.com www.linux.com访问主页面 friend.linux.com访问交友页面 blog.linux.com访问博客页 ...

  2. Java实现 LeetCode 770 基本计算器 IV(暴力+分析题)

    770. 基本计算器 IV 给定一个表达式 expression 如 expression = "e + 8 - a + 5" 和一个求值映射,如 {"e": ...

  3. Java实现 LeetCode 761 特殊的二进制序列(括号问题)

    761. 特殊的二进制序列 特殊的二进制序列是具有以下两个性质的二进制序列: 0 的数量与 1 的数量相等. 二进制序列的每一个前缀码中 1 的数量要大于等于 0 的数量. 给定一个特殊的二进制序列 ...

  4. Java实现 蓝桥杯 算法训练 Beaver's Calculator

    试题 算法训练 Beaver's Calculator 问题描述 从万能词典来的聪明的海狸已经使我们惊讶了一次.他开发了一种新的计算器,他将此命名为"Beaver's Calculator ...

  5. Java实现 LeetCode 689 三个无重叠子数组的最大和(换方向筛选)

    689. 三个无重叠子数组的最大和 给定数组 nums 由正整数组成,找到三个互不重叠的子数组的最大和. 每个子数组的长度为k,我们要使这3*k个项的和最大化. 返回每个区间起始索引的列表(索引从 0 ...

  6. Java实现 LeetCode 386 字典序排数

    386. 字典序排数 给定一个整数 n, 返回从 1 到 n 的字典顺序. 例如, 给定 n =1 3,返回 [1,10,11,12,13,2,3,4,5,6,7,8,9] . 请尽可能的优化算法的时 ...

  7. Java实现 LeetCode 198 打家劫舍

    198. 打家劫舍 你是一个专业的小偷,计划偷窃沿街的房屋.每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报 ...

  8. Java实现 LeetCode 166 分数到小数

    166. 分数到小数 给定两个整数,分别表示分数的分子 numerator 和分母 denominator,以字符串形式返回小数. 如果小数部分为循环小数,则将循环的部分括在括号内. 示例 1: 输入 ...

  9. Android中如何使用GridView

    首先在主XML中放入Grid View控件 取好id private GridView gv1; private int[] icon = {R.drawable.cat, R.drawable.co ...

  10. 有趣的 Canvas

    canvas动画狗:https://www.jianshu.com/p/7873307147d5