首页 > 其他分享 >整数划分 题解

整数划分 题解

时间:2024-02-17 15:12:26浏览次数:29  
标签:输出 int 题解 memset long 划分 整数 1005 sizeof

题目描述

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

输入格式

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

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

输出格式

对于每组数据

第一行输出最大值。

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

样例

样例输入

1
199 2

样例输出

171
19 9

题解

拿到题第一眼,这不典型的DFS吗;

看了眼数据范围。。。

果断放弃DFS;

仔细读题,发现有“划分次数”这样带有明显阶段性的词语,很难不让人想到DP;

将一个整数划分成一个个区间,这提示了我们DP的种类:区间DP(其实种类知道不知道都一样);

定义f[i][j]表示前i位截了j次所能达到的最大价值;

初始化$$f[i][1] = a[1][i]$$其中a[i][j]表示从第i位到第j位的数;

例如,对于数12345,a[3][5] == 345;

状态转移方程$$f[i][j] = max(f[i][j], f[k][j - 1] * a[k + 1][i])$$ 其中k为断点,需要从1到i - 1枚举(很简单,不再详细解释);

我们发现,a数组需要预处理出来,其实可以采用区间DP的思想,在这里我采用的是一个非常麻烦的个人思路,但也能出来正确结果;

接下来就是输出路径的问题了;

定义g[i][j]表示前i位划分j次如果要达到最大值需要的断点,每次更新f数组时顺便将g数组更新;

输出时,我们只需从m开始倒序遍历,每划分一次就输出一次,同时更新总长度的值(因为已经输出的值对于我们来说是无用的),这样就可以输出路径;

具体看代码

代码

#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;
long long n, m;
int t;
long long a[1005][1005];
long long f[1005][1005]; //长度,次数; 
long long g[1005][1005];
int b[105];
int c[105];
int main() {
	cin >> t;
	for (int pp = 1; pp <= t; pp++) {
		cin >> n >> m;
		memset(a, 0, sizeof(a));
		memset(f, 0, sizeof(f));
		memset(b, 0, sizeof(b));
		memset(c, 0, sizeof(c));
		memset(g, 0, sizeof(g));
		long long o = 1; //输入的数的总位数
		while(n) {
			b[o] = n % 10;
			n /= 10;
			o++;
		}
		o--;
		for (int i = 1; i <= o; i++) {
			c[i] = b[o - i + 1];
		}
		for (int i = 1; i <= o; i++) {
			for (int j = 1; j <= o; j++) {
				int p = i;
				for (int k = j - i + 1; k >= 1; k--) {
					a[i][j] += (pow(10, k)) * c[p];
					p++;
				}
				a[i][j] /= 10;
			}
		} //上面都是预处理数组a;
		for (int i = 1; i <= o; i++) {
			f[i][1] = a[1][i]; //初始化;
		}
		for (int j = 2; j <= m; j++) {
			for (int i = 1; i <= o; i++) {
				for (int k = 1; k < i; k++) {
					if (f[i][j] <= f[k][j - 1] * a[k + 1][i]) {
						f[i][j] = f[k][j - 1] * a[k + 1][i];
						g[i][j] = k;
					}
				}
			}
		}
		cout << f[o][m] << endl;
		long long ans[10005] = {0};
		int t = 0;
		for (int i = m; i >= 1; i--) {
			ans[++t] = a[g[o][i] + 1][o]; //这里的g[o][i]要+1是因为我们的a数组是包含左右端点的;
			o = g[o][i]; //减小长度,已经输出的对我们来说无用;
		}
		for (int i = t; i >= 1; i--) {
			cout << ans[i] << ' ';
		}
		cout << endl;
	}
	return 0;
}

标签:输出,int,题解,memset,long,划分,整数,1005,sizeof
From: https://www.cnblogs.com/PeppaEvenPig/p/18017880

相关文章

  • 情书密码 题解
    题目描述有消息称:绝恋找到了自己的MissRight,正准备自己的表白。绝恋已经写好了情书,但为了避免其它人截获,他对情书进行加密。为了打探绝恋的私密,你冒着生命危险终于搞到了这封情书。原以为可以轻易将情书解密,结果竟然发现聪明的绝恋并没有直接写出加密用的密码,而是在那粉红色的......
  • CF484B题解
    朴素的办法是枚举每两个数然后更新取模的结果。时间复杂度为\(O(n^2)\)不能通过。这个朴素的过程可以看作枚举一个数然后找对其取模最大值的过程。我们可以枚举一个数,然后再枚举以它的倍数为两端的区间,找其中取模的最大值。找最大值的过程可以二分或双指针。值域很小,也可以......
  • 牛客小白87题解A-G
    A小苯的石子游戏本题贪心模拟即可B小苯的排序疑惑考虑到最简单的操作把n-1个数排好,最后一个看能否有序。即:a[1]<=min(a[2],a[3],a[4]..,a[n])||a[n]>=max(a[1],a[2],a[3]....,a[n-1])满足条件,反之易得不可能C&D小苯的IDE括号问题本题考察题意理解,简单版本我们可以只关注逻......
  • 0217-0224校赛部分题解
    SMUWinter2024Round#3(Div.2)对于自己比较有价值的题目是D题https://codeforces.com/gym/102897/problem/D?mobile=trueJ题https://codeforces.com/gym/102897/problem/JK题https://codeforces.com/gym/102897/problem/KE题https://codeforces.com/gym/102897/prob......
  • 关于thrift python接口和java通信出现问题解决
    真的无语,搞了一个下午。使用thrift出现错误,先说一下遇到第一个错误,如下图:那时候代码是这叼样```if__name__=='__main__':handler=MessageServiceHandler()processor=MessageService.Processor(handler)transport=TSocket.TServerSocket(None,"9090"......
  • P3157 [CQOI2011] 动态逆序对 题解
    题目链接:动态逆序对常见经典题,理解一个数对逆序对贡献计算即可。对于一个数而言,它在一个序列中的逆序对有两部分贡献,一部分为前面比它严格大的数,另一部分为后面比它严格小的数,有道二莫题也是基于此去考虑的。考虑最开始知道了总逆序数,每次删除一个数逆序数会减少两部分值,显然就......
  • 选课 题解
    题目描述大学里实行学分。每门课程都有一定的学分,学生只要选修了这门课并考核通过就能获得相应的学分。学生最后的学分是他选修的各门课的学分的总和。每个学生都要选择规定数量的课程。其中有些课程可以直接选修,有些课程需要一定的基础知识,必须在选了其它的一些课程的基础上才......
  • 洛谷 P4065 题解
    模拟赛T1,纪念一下第一次场切紫。(话说场上这么多人切是不是都找到原了,就我这么傻想了半天)正难则反,很容易的将题目转化为选择若干种颜色,使这些颜色在原数组中的位置连续。设$pre_i$为颜色$i$最早出现的位置,$suf_i$为颜色$i$最晚出现的位置。假设通过选择若干颜色得到的位......
  • P10149 [Ynoi1999] XM66F题解
    题解首先,问题是静态的区间查询问题,一眼莫队。那么我们就需要考虑所需要维护的内容在区间扩增或者缩减时的变化如何快速维护。我们可以先写出对于区间\([l,r]\)来说,满足\(l\lei<j<k\ler\)的有序三元组\((i,j,k)\)数量的表达式,方便拆式子:\[\sum\limits_{i=l}^{r}......
  • 启动vue-element-admin遇到问题解决方案
    概述从https://github.com/PanJiaChen/vue-element-admin下载代码,按照文档执行,期间遇到一些列问题。1#clonetheproject2gitclonehttps://github.com/PanJiaChen/vue-element-admin.git34#entertheprojectdirectory5cdvue-element-admin67#insta......