4th IIUC Inter-University Programming Contest, 2005 | |
F | Marks Distribution |
Input: standard input | |
Problemsetter: Md. Bahlul Haider |
In an examination one student appeared in N subjects and has got total T marks. He has passed in all the N subjects where minimum mark for passing in each subject is P. You have to calculate the number of ways the student can get the marks. For example, if N=3, T=34 andP=10 then the marks in the three subject could be as follows.
Subject 1 | Subject 2 | Subject 3 | |
1 | 14 | 10 | 10 |
2 | 13 | 11 | 10 |
3 | 13 | 10 | 11 |
4 | 12 | 11 | 11 |
5 | 12 | 10 | 12 |
6 | 11 | 11 | 12 |
7 | 11 | 10 | 13 |
8 | 10 | 11 | 13 |
9 | 10 | 10 | 14 |
10 | 11 | 12 | 11 |
11 | 10 | 12 | 12 |
12 | 12 | 12 | 10 |
13 | 10 | 13 | 11 |
14 | 11 | 13 | 10 |
15 | 10 | 14 | 10 |
So there are 15 solutions. So F (3, 34, 10) = 15.
Input
In the first line of the input there will be a single positive integer K followed by K lines each containing a single test case. Each test case contains three positive integers denoting N, T and P respectively. The values of N, T and P will be at most 70. You may assume that the final answer will fit in a standard 32-bit integer.
Output
For each input, print in a line the value of F (N, T, P).
Sample Input | Output for Sample Input |
2 | 15 |
题意:给定n,t,p,求n个人,每个人最少p,总和为t有多少种分法。
思路:dp。i表示第i个人,j表示总和为j。状态转移方程为f[i][j] += f[i - 1][j - k];
代码:
#include <stdio.h>
#include <string.h>
int T, n, t, p, f[75][75];
int main() {
scanf("%d", &T);
while (T --) {
scanf("%d%d%d", &n, &t, &p);
int num = t - n * p;
for (int i = 0; i <= num; i ++)
f[1][i] = 1;
for (int i = 2; i <= n; i ++) {
for (int j = 0; j <= num; j ++) {
f[i][j] = 0;
for (int k = 0; k <= j; k ++) {
f[i][j] += f[i - 1][j - k];
}
}
}
printf("%d\n", f[n][num]);
}
return 0;
}