2.2 立方数之和 UVa11137

1.题目描述:点击打开链接

2.解题思路:本题利用递推关系解决。建立一个多段图,定义状态d(i,j)表示“使用不超过i的整数的立方,累加和为j”的方案数。那么根据加法原理,如果没有选择数字i的立方和就得到了j,那么方案数就是d(i-1,j);如果选择了数字i的立方和才得到了j,那么方案数是d(i,j-i^3)。即:

d(i,j)=d(i-1,j)+d(i,j-i^3);

这个递推式还可以降低维度,利用滚动数组计算。由递推式可知,i,j都需要从小到大计算,而更新i的时候,d(j)保存的是第i-1次计算时的结果,此时可以用d(j)更新d(j+i^3)的状态。即只需要d(j+i^3)+=d(j)即可完成上述方程的计算。

3.代码:

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<string>
#include<sstream>
#include<set>
#include<vector>
#include<stack>
#include<map>
#include<queue>
#include<deque>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#include<functional>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> P;
typedef pair<long long, long long> PL;
#define me(s) memset(s,0,sizeof(s))
#define For(i,n) for(int i=0;i<(n);i++)

#define N 10000+10
#define M 25
ll d[N];
void init()
{
	me(d);
	d[0] = 1;
	for (int i = 1; i < M; i++)
	{
		int c = i*i*i;
		for (int j = 0; j < N; j++)
		{
			if (j + c < N)
				d[j + c] += d[j];//利用滚动数组计算,用d(j)去更新d(i+c)
			else break;
		}
	}

}
int main()
{
	//freopen("t.txt", "r", stdin);
	int n;
	init();
	while (cin >> n)
	{
		cout << d[n] << endl;
	}
	return 0;
}
时间: 2024-12-27 19:20:18

2.2 立方数之和 UVa11137的相关文章

UVA - 11137 Ingenuous Cubrency[背包DP]

People in Cubeland use cubic coins. Not only the unit of currency iscalled a cube but also the coins are shaped like cubes and their valuesare cubes. Coins with values of all cubic numbers up to 9261(= 213),i.e., coins with the denominations of 1, 8,

第2本:《信息简史》

第2本:<信息简史> 这 本<信息简史>读起来相当吃力,实际上我只是感觉第1章会说话的鼓.第4章齿轮机械.第5章的电报与密码.第12章的随机数有些意思,其它章节读起来是断 断续续,看来自己的信息水平有限.最莫名其妙的是书后的几段书评了,新东方老师也来点评此书,真不知道他们是不是读了此书,是如何读下去的,如果真是一本 有关信息的好书,也不用找一些人凑上一堆书评吧. 第1章 会说话的鼓(似是而非的编码) 第2章 持久的文字(心智中并无词典) 第3章 两本词典(我们文字的不确定性以及我们

递推关系的运用加简单DP【UVA11137Ingenuous Cubrency】-------2015年1月27日

一:题意描述 本题就是求立方数之和.输入正整数n,求将n写成若干个正整数的立方和有多少种方法? 二:问题分析 本题主要的难点就是确定状态.我们可以建立多段图.节点(i,j)表示“使用不超过i的整数的立方,累加和为j“这个状态.设d(i,j)表示为从(0,0)到(i,j)的路径条数,最终答案 是d(21,n).对于这个图而言,每一个节点(i,j)都只能从当前节点(i,j)到达节点(i+1,a*(j+1)^3+j)(a为j+a*(j+1)^3<maxn的常数)所以我们可以写出如下代码: #inclu

noip复习之数学(2)——递推关系

1.问题一:兔子的繁殖(斐波拉契数列) ? f[n]=f[n-1]+f[n-2] \[ Fibonacci:f(n)=\frac{1}{\sqrt{5}}\left(\frac{1+\sqrt{5}}{2}\right)^n-\frac{1}{\sqrt{5}}\left(\frac{1-\sqrt{5}}{2}\right)^n \] 问题二:凸三角形剖分/括号化问题/不同出栈次序数问题/二叉树个数问题(卡特兰数) f[n]=f[2]f[n-1]+f[3]f[n-2]+...+f[n-1]f[

数论-整除与同余

\chapter{数论} \begin{example}(1995年初联)试证:每个大于$6$的自然数$n$, 都可以表示为两个大于$1$且互质的自然数之和.\end{example}\begin{solution}\begin{enumerate} \item 当$n$是奇数,则$n=2+(n-2)$且$n-2$是大于$1$的奇数, $n-2$与$2$互质; \item 若$n$是偶数, \begin{enumerate} \item 若$\frac{n}{2}$是偶数,则$n=\left(\

相加之和为某个数n,求方法数 ------------ 动态规划的方法

uva11137 n3可转化为n2(立方和为n的方法数) /* ID: neverchanje PROG: LANG: C++11 */ #include<iostream> #include<cstring> #include<cstdio> typedef long long ll; using namespace std; int n; long long d[23][maxn]; //下标<=21 int main(){ memset(d,0,sizeof

幸运抽奖,分解一个千位数求各位数之和

import java.util.Scanner; /** * @author 蓝色以太 * 幸运抽奖 */ public class LuckyDraw { public static void main(String[] args) { Scanner sc=new Scanner(System.in); System.out.println("请输入4位会员卡号:"); int num=sc.nextInt(); int ge=num%10; int shi=num%100/10

数学:求一个数的真约数(因数)的个数及所有约数之和

一. 我们知道,每个自然数(不包括0和1)都有2个以上的因数,因数最少的是质数(也叫素数),质数的因数是1和它本身.非质数的自然数也叫合数,它们都含有3个以上(含3个)的因数. 1.怎样求一个数有多少个因数? 对于一个已知的自然数,要求出它有多少个因数,可用下列方法: 首先将这个已知数分解质因数,将此数化成几个质数幂的连乘形式,然后把这些质数的指数分别加一,再相乘,求出来的积就是我们要的结果. 例如:求360有多少个因数. 因为360分解质因数可表示为:360=2^3×3^2×5,2.3.5的指

计算数组的最大子序列之和

问题描述: 计算一个给定数组的最大子序列之和 分析: 有三种方法: 1,扫描3遍,可以计算所有的子序列之和,但是复杂度为N^3. 2,扫描2遍,计算以任意元素开始的和,如果大于当前的最大值则将最大值付给它,复杂度为N^2. 3,扫描一遍,计算任意元素开始的值,如果小于零则清零,否则继续往后加. 代码实现: package c02; /**  * @project: DataStructureAndAlgorithmAnalysis  * @filename: MaxSubSum  * @vers