There is a test that has n types of questions. You are given an integer
target and a 0-indexed 2D integer array types where types[i] = [counti, marksi] indicates that there are counti questions of the ith
type, and each one of them is worth marksi points.
Return _the number of ways you can earnexactly _targetpoints in the exam. Since the answer may be too large, return it modulo10^9 + 7.
Note that questions of the same type are indistinguishable.
For example, if there are 3 questions of the same type, then solving the 1st and 2nd questions is the same as solving the 1st and 3rd questions, or the 2nd and 3rd questions.
Input: target =6, types =[[6,1],[3,2],[2,3]]Output: 7Explanation: You can earn 6 points in one of the seven ways:- Solve 6 questions of the 0th type:1+1+1+1+1+1=6- Solve 4 questions of the 0th type and 1 question of the 1st type:1+1+1+1+2=6- Solve 2 questions of the 0th type and 2 questions of the 1st type:1+1+2+2=6- Solve 3 questions of the 0th type and 1 question of the 2nd type:1+1+1+3=6- Solve 1 question of the 0th type,1 question of the 1st type and 1 question of the 2nd type:1+2+3=6- Solve 3 questions of the 1st type:2+2+2=6- Solve 2 questions of the 2nd type:3+3=6
Input: target =5, types =[[50,1],[50,2],[50,5]]Output: 4Explanation: You can earn 5 points in one of the four ways:- Solve 5 questions of the 0th type:1+1+1+1+1=5- Solve 3 questions of the 0th type and 1 question of the 1st type:1+1+1+2=5- Solve 1 questions of the 0th type and 2 questions of the 1st type:1+2+2=5- Solve 1 question of the 2nd type:5
This is a variation of the bounded knapsack problem. For each type, you can pick 0 to counti questions, each worth marksi points. Use DP to count the number of ways to reach exactly target points.
classSolution {
publicintwaysToReachTarget(int target, int[][] types) {
int mod = 1_000_000_007;
int[] dp =newint[target+1];
dp[0]= 1;
for (int[] t : types) {
int cnt = t[0], mark = t[1];
int[] ndp = dp.clone();
for (int i = 1; i <= cnt; i++) {
for (int j = target; j >= i*mark; j--) {
ndp[j]= (ndp[j]+ dp[j-i*mark]) % mod;
}
}
dp = ndp;
}
return dp[target];
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
classSolution {
funwaysToReachTarget(target: Int, types: Array<IntArray>): Int {
val mod = 1_000_000_007
var dp = IntArray(target+1)
dp[0] = 1for (t in types) {
val cnt = t[0]; val mark = t[1]
val ndp = dp.copyOf()
for (i in1..cnt) {
for (j in target downTo i*mark) {
ndp[j] = (ndp[j] + dp[j-i*mark]) % mod
}
}
dp = ndp
}
return dp[target]
}
}
1
2
3
4
5
6
7
8
9
10
11
12
classSolution:
defwaysToReachTarget(self, target: int, types: list[list[int]]) -> int:
mod =10**9+7 dp = [0]*(target+1)
dp[0] =1for cnt, mark in types:
ndp = dp[:]
for i in range(1, cnt+1):
for j in range(target, i*mark-1, -1):
ndp[j] = (ndp[j] + dp[j-i*mark]) % mod
dp = ndp
return dp[target]