Description
牛客网 2018校招真题 整数求和
Solving Ideas
动态规划
State:
dp[i][j]
: 在[1, …, i]中取若干个整数求和等于j的组合的个数
Initial State:
dp[0][j] = 0;
(1<=j<=m)dp[i][0] = 1;
(0<=i<=n)
State Transition:
if (j - i >= 0) dp[i][j] = dp[i - 1][j] + dp[i - 1][j - i];
(i > 0)
else dp[i][j] = dp[i - 1][j];
(i > 0)
Time complexity :
O
(
n
∗
m
)
O(n*m)
O(n∗m)
Space complexity :
O
(
n
∗
m
)
O(n*m)
O(n∗m)
Solution
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* Dynamic Programming
*
* State:
* dp[i][j]: 在[1, ..., i]中取若干个整数求和等于j的组合的个数
*
* Initial State:
* dp[0][j] = 0; (1<=j<=m)
* dp[i][0] = 1; (0<=i<=n)
*
* State Transition:
* if (j - i >= 0) dp[i][j] = dp[i - 1][j] + dp[i - 1][j - i]; (i > 0)
* else dp[i][j] = dp[i - 1][j]; (i > 0)
*
* @author wylu
*/
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] strs = br.readLine().split(" ");
int n = Integer.parseInt(strs[0]), m = Integer.parseInt(strs[1]);
int[][] dp = new int[n + 1][m + 1];
for (int i = 0; i <= n; i++) dp[i][0] = 1;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (j - i >= 0) {
dp[i][j] = dp[i - 1][j] + dp[i - 1][j - i];
}else {
dp[i][j] = dp[i - 1][j];
}
}
}
System.out.println(dp[n][m]);
}
}
优化,将空间复杂度降至 O ( m ) O(m) O(m)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] strs = br.readLine().split(" ");
int n = Integer.parseInt(strs[0]), m = Integer.parseInt(strs[1]);
//dp[i]: 从[1, ..., n]中取若干个数求和等于m的组合的个数
int[] dp = new int[m + 1];
dp[0] = 1;
for (int i = 1; i <= n; i++) {
for (int j = m; j >= i; j--) {
dp[j] += dp[j - i];
}
}
System.out.println(dp[m]);
}
}