牛客 小米 最少立方数之和 记忆化搜索

本文探讨了如何将一个数字N分解为最少数量的立方数之和的问题,通过动态规划算法解决,提供了详细的代码实现和解释。
摘要由CSDN通过智能技术生成

链接:https://www.nowcoder.com/questionTerminal/4bc284dc9d0144628a722eb5d1191ef3?answerType=1&f=discussion
来源:牛客网

给出一个数字N(0<N<1000000),将N写成立方数和的形式,求出需要的最少立方数个数。
例如N=17,1+8+8 = 17,最少需要3个立方数,则输出3。
N= 28,1+1+1+1+8+8+8=28, 需要7个立方数,1+27=28,需要2个立方数,所以最少立方数为2,则输出2。

输入描述:

一个数字N(0<N<1000000)

输出描述:

最少立方数个数

示例1
输入

28

输出

2


https://www.nowcoder.com/practice/4bc284dc9d0144628a722eb5d1191ef3?tpId=125&&tqId=33735&rp=1&ru=/activity/oj&qru=/ta/exam-xiaomi/question-ranking

数字 N N N,可以把 N N N分解成若干个立方数相加

如 : 17 = 1 + 8 + 8, 28 = 1+1+1+1+ 8 + 8 + 8

给定 N N N,问最少可以分解成几个数

  • n n n的子问题是

    • n − 1 ∗ 1 ∗ 1 n-1 * 1 * 1 n111
    • n − 2 ∗ 2 ∗ 2 n-2 * 2 * 2 n222
    • n − 3 ∗ 3 ∗ 3 n - 3 * 3 * 3 n333
    • . . . . . ..... .....
    • n − k ∗ k ∗ k     且 ( k ∗ k ∗ k < = n ) n-k * k *k~~~且(k * k * k <=n) nkkk   (kkk<=n)
  • 所以 n n n的答案就是从子问题里选最小

    d p ( n ) = m i n ( a n s n , d p ( n − k ∗ k ∗ k ) + 1 ) dp(n) = min(ans_n, dp(n-k * k * k)+1) dp(n)=min(ansn,dp(nkkk)+1)

    int mem[MAXN];
    int dp(int n) {
    	if(n <= 0) return 0;
    	if(INF != mem[n]) return mem[n];
    	int i = 1;
    	while(i*i*i <= n) {
    		mem[n] = min(mem[n], dp(n-i*i*i)+1);
    		i ++;
    	}
    	return mem[n];
    }
    

动态规划解法

memset(dp, INF, sizeof(dp));
dp[0] = 0;              //边界条件为dp[0] = 0;
for(int i=1; i<=n; i++)
	for(int j=1; j*j*j<=i; j++)
		dp[i] = min(dp[i], dp[i-j*j*j]+1);
cout << dp[n] << endl;

完整代码

#define debug
#ifdef debug
#include <time.h>
#include "/home/majiao/mb.h"
#endif

#include <iostream>
#include <algorithm>
#include <vector>
#include <string.h>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <math.h>

#define MAXN ((int)1e6+7)
#define ll long long 
#define INF (0x7f7f7f7f)
#define fori(lef, rig) for(int i=lef; i<=rig; i++)
#define forj(lef, rig) for(int j=lef; j<=rig; j++)
#define fork(lef, rig) for(int k=lef; k<=rig; k++)
#define QAQ (0)

using namespace std;

#define show(x...) \
	do { \
		cout << "\033[31;1m " << #x << " -> "; \
		err(x); \
	} while (0)

void err() { cout << "\033[39;0m" << endl; }
template<typename T, typename... A>
void err(T a, A... x) { cout << a << ' '; err(x...); }

namespace FastIO {

	char print_f[105];
	void read() { }
	void print() { putchar('\n'); }

	template <typename T, typename... T2>
		inline void read(T &x, T2 &... oth) {
			x = 0;
			char ch = getchar();
			ll f = 1;
			while (!isdigit(ch)) {
				if (ch == '-') f *= -1; 
				ch = getchar();
			}
			while (isdigit(ch)) {
				x = x * 10 + ch - 48;
				ch = getchar();
			}
			x *= f;
			read(oth...);
		}
	template <typename T, typename... T2>
		inline void print(T x, T2... oth) {
			ll p3=-1;
			if(x<0) putchar('-'), x=-x;
			do{
				print_f[++p3] = x%10 + 48;
			} while(x/=10);
			while(p3>=0) putchar(print_f[p3--]);
			putchar(' ');
			print(oth...);
		}
} // namespace FastIO
using FastIO::print;
using FastIO::read;

int mem[MAXN];
int dp(int n) {
	if(n <= 0) return 0;
	if(INF != mem[n]) return mem[n];
	int i = 1;
	while(i*i*i <= n) {
		mem[n] = min(mem[n], dp(n-i*i*i)+1);
		i ++;
	}
	return mem[n];
}

int main() {
#ifdef debug
	freopen("test", "r", stdin);
	// freopen("out_main", "w", stdout);
	clock_t stime = clock();
#endif
	int n;
	cin >> n;
	memset(mem, INF, sizeof(mem));
	int ans = dp(n);
	cout << ans << endl;

#ifdef debug
	clock_t etime = clock();
	printf("rum time: %lf 秒\n",(double) (etime-stime)/CLOCKS_PER_SEC);
#endif 
	return 0;
}




内容概要:该题库专为研究生入学考试计算机组成原理科目设计,涵盖名校考研真题、经典教材课后习题、章节题库和模拟试题四大核心模块。名校考研真题精选多所知名高校的计算机组成原理科目及计算机联考真题,并提供详尽解析,帮助考生把握考研命题趋势与难度。经典教材课后习题包括白中英《计算机组成原理》(第5版)和唐朔飞《计算机组成原理》(第2版)的全部课后习题解答,这两部教材被众多名校列为考研指定参考书目。章节题库精选代表性考题,注重基础知识与重难点内容,帮助考生全面掌握考试大纲要求的知识点。模拟试题依据历年考研真题命题规律和热门考点,精心编制两套全真模拟试题,并附标准答案,帮助考生检验学习成果,评估应试能力。 适用人群:计划参加研究生入学考试并报考计算机组成原理科目的考生,尤其是需要系统复习和强化训练的学生。 使用场景及目标:①通过研读名校考研真题,考生可以准确把握考研命题趋势与难度,有效评估复习成效;②通过经典教材课后习题的练习,考生可以巩固基础知识,掌握解题技巧;③通过章节题库的系统练习,考生可以全面掌握考试大纲要求的各个知识点,为备考打下坚实基础;④通过模拟试题的测试,考生可以检验学习成果,评估应试能力,为正式考试做好充分准备。 其他说明:该题库不仅提供详细的题目解析,还涵盖了计算机组成原理的各个方面,包括计算机系统概述、据表示与运算、存储器分层、指令系统、中央处理器、总线系统和输入输出系统等。考生在使用过程中应结合理论学习与实践操作,注重理解与应用,以提高应试能力和专业知识水平。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值