状 态 表 示 : 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;
}
}
降维(利用滚动数组)
合并得最终的状态转移方程为:
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)
由状态方程可知,需要利用的仅有当前行和上一行所以可以利用滚动数组的概念将二维降至一维,即:
f ( j ) = f ( j ) + f ( j − i ) f(j) = f(j) + f(j-i) f(j)=f(j)+f(j−i)
核心代码:
for(int i=1;i<=n;i++) {
for(int j=i;j<=n;j++) {
dp[j] = (dp[j]+dp[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;
# 总结
本文从基础到高级再到实战,由浅入深,把MySQL讲的清清楚楚,明明白白,这应该是我目前为止看到过最好的有关MySQL的学习笔记了,我相信如果你把这份笔记认真看完后,无论是工作中碰到的问题还是被面试官问到的问题都能迎刃而解!
**重要的事:需要领取完整版的MySQL学习笔记的话,请转发+关注后[点这里免费获取](https://codechina.csdn.net/m0_60958482/java-p7)到免费的下载方式!**
**MySQL50道高频面试题整理:**
应该是我目前为止看到过最好的有关MySQL的学习笔记了,我相信如果你把这份笔记认真看完后,无论是工作中碰到的问题还是被面试官问到的问题都能迎刃而解!
**重要的事:需要领取完整版的MySQL学习笔记的话,请转发+关注后[点这里免费获取](https://codechina.csdn.net/m0_60958482/java-p7)到免费的下载方式!**
**MySQL50道高频面试题整理:**
![](https://img-blog.csdnimg.cn/img_convert/7c3679d466694272a51d2fb9f24f2e32.png)