题目描述
一个正整数 n 可以表示成若干个正整数之和,形如:n=n1+n2+…+nk,其中 n1≥n2≥…≥nk,k≥1。
我们将这样的一种表示称为正整数 n 的一种划分。
现在给定一个正整数 n,请你求出 n 共有多少种不同的划分方法。
输入格式
共一行,包含一个整数 n。
输出格式
共一行,包含一个整数,表示总划分数量。
由于答案可能很大,输出结果请对 10^9+7 取模。
数据范围
1≤n≤1000
输入样例:
5
输出样例:
7
思路(朴素版)
状 态 表 示 : f ( i , j ) , 表 示 从 1 i 中 选 刚 好 可 以 拼 成 j 的 所 有 方 法 状态表示:f(i,j),表示从1~i中选刚好可以拼成j的所有方法 状态表示:f(i,j),表示从1 i中选刚好可以拼成j的所有方法
属 性 : 数 量 属性:数量 属性:数量
核 心 : 最 后 一 个 数 i 不 取 或 者 取 k 个 正 好 拼 成 j 核心:最后一个数i不取或者取k个正好拼成j 核心:最后一个数i不取或者取k个正好拼成j
状 态 划 分 : f ( i − 1 , j ) 取 0 个 i , 1 个 i … … , k 个 i 变 为 f ( i , j ) 状态划分:f(i-1,j)取0个i,1个i……,k个i变为f(i,j) 状态划分:f(i−1,j)取0个i,1个i……,k个i变为f(i,j)
由状态划分可得到状态转移方程:
f ( i , j ) = f ( i − 1 , j ) + f ( i − 1 , j − i ) + f ( i − 1 , j − 2 i ) + … … + f ( i − 1 , j − k i ) f(i,j) = f(i-1,j)+f(i-1,j-i)+f(i-1,j-2i)+……+f(i-1,j-ki) f(i,j)=f(i−1,j)+f(i−1,j−i)+f(i−1,j−2i)+……+f(i−1,j−ki)
f ( i , j − i ) = f ( i − 1 , j − i ) + f ( i − 1 , j − 2 i ) + … … + f ( i − 1 , j − k i ) f(i,j-i) = ~~~~~~~~~~~~~~~f(i-1,j-i)+f(i-1,j-2i)+……+f(i-1,j-ki) f(i,j−i)= f(i−1,j−i)+f(i−1,j−2i)+……+f(i−1,j−ki)
相减得最终的状态转移方程:
f ( i , j ) = f ( i − 1 , j ) + f ( i , j − i ) f(i,j) = f(i-1,j)+f(i,j-i) f(i,j)=f(i−1,j)+f(i,j−i)
核心代码
for(int i=1;i<=n;i++) {
for(int j=0;j<=n;j++) {
dp[i][j] = dp[i - 1][j] % MOD; // 如果容量j小于i的话,不能对i进行选择。
if (j >= i) { //只有容量j大于等于i时,才能对i的选择多少进行讨论
dp[i][j] = (dp[i-1][j]+dp[i][j-i]) % MOD;
}
}
}
完整代码
package acWing900;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
public class Main {
static int N = 1010,MOD = (int) (1e9+7);
static int n;
static int dp[][] = new int[N][N];
public static void main(String[] args) throws Exception{
Read r = new Read();
n = r.nextInt();
for(int i=1;i<=n;i++) {
dp[0][i] = 0; // 当容量为i有0个物品一个则没有方案。
}
for(int i=0;i<=n;i++) {
dp[i][0] = 1; // 当容量为0前i个物品一个不选也是一种方案。
}
// 特殊 dp[0][0] = 1
for(int i=1;i<=n;i++) {
for(int j=0;j<=n;j++) {
dp[i][j] = dp[i - 1][j] % MOD; // 如果容量j小于i的话,不能对i进行选择。
if (j >= i) { //只有容量j大于等于i时,才能对i的选择多少进行讨论
dp[i][j] = (dp[i-1][j]+dp[i][j-i]) % MOD;
}
}
}
System.out.println(dp[n][n]);
}
class Read{
StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
public int nextInt() throws Exception{
st.nextToken();
return (int)st.nval;
}
}
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
Java核心架构进阶知识点
面试成功其实都是必然发生的事情,因为在此之前我做足了充分的准备工作,不单单是纯粹的刷题,更多的还会去刷一些Java核心架构进阶知识点,比如:JVM、高并发、多线程、缓存、Spring相关、分布式、微服务、RPC、网络、设计模式、MQ、Redis、MySQL、设计模式、负载均衡、算法、数据结构、kafka、ZK、集群等。而这些也全被整理浓缩到了一份pdf——《Java核心架构进阶知识点整理》,全部都是精华中的精华,本着共赢的心态,好东西自然也是要分享的
内容颇多,篇幅却有限,这就不在过多的介绍了,大家可根据以上截图自行脑补
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
外链图片转存中…(img-fVm6D3xN-1713296888569)]
[外链图片转存中…(img-x3qkap8N-1713296888569)]
内容颇多,篇幅却有限,这就不在过多的介绍了,大家可根据以上截图自行脑补
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!