来源:牛客网
妞妞参加了Nowcoder Girl女生编程挑战赛, 但是很遗憾, 她没能得到她最喜欢的黑天鹅水晶项链。
于是妞妞决定自己来制作一条美丽的项链。一条美丽的项链需要满足以下条件:
1、需要使用n种特定的水晶宝珠
2、第i种水晶宝珠的数量不能少于li颗, 也不能多于ri颗
3、一条美丽的项链由m颗宝珠组成
妞妞意识到满足条件的项链种数可能会很多, 所以希望你来帮助她计算一共有多少种制作美丽的项链的方案。
输入描述:
输入包括n+1行, 第一行包括两个正整数(1 <= n <= 20, 1 <= m <= 100), 表示水晶宝珠的种数和一条美丽的项链需要的水晶宝珠的数量。
接下来的n行, 每行两个整数li, ri(0 <= li <= ri <= 10), 表示第i种宝珠的数量限制区间。
输出描述:
输出一个整数, 表示满足限定条件的方案数。保证答案在64位整数范围内。
输入
3 5 0 3 0 3 0 3
输出
12
思路:如果n的个数确定可以采用多重循环嵌套,但是由n的个数不确定,思考后可以考虑递归来做,但是递归重复计算次数太多,因而想到可以采用动态规划解决此问题。
设d[i][j]表示i+1种宝珠中取j个宝珠的方案数
k表示宝珠个数上限-宝珠个数下限
则d[i][j]=d[i-1][j]+d[i-1][j-1].....+d[i-1][j-k]
例如:当2种宝珠选2个时的方案数
d[1][2]=d[0][2]+d[0][1]+d[0][0](选择从第2种宝珠中取i个时的方案数等于从第1种宝珠中分别取2个,取1个,取0个的和)
使用动态规划可得以下二维数组:
| 0 | 1 | 2 | 3 | 4 | 5 |
0 | 1 | 1 | 1 | 1 | 0 | 0 |
1 | 1 | 2 | 3 | 4 | 3 | 2 |
2 | 1 | 3 | 6 | 10 | 12 | 12 |
java代码如下:
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in=new Scanner(System.in);
int n;
int m;
n=in.nextInt();
m=in.nextInt();
int l;
int r;
int[] array=new int[n];
for(int i=0;i<n;i++) {
l=in.nextInt();
r=in.nextInt();
array[i]=r-l;
m=m-l;
}
in.close();
long[][] d=new long[n][m+1];
for(int i=0;i<=array[0];i++) {//当一种宝珠的取上限个时方案数都为1
d[0][i]=1;
}
for(int i=1;i<n;i++) {
for(int j=0;j<=m;j++) {
if(j==0) {
d[i][j]=1;
}else {
long sum=0;
for(int k=0;k<=array[i]&&k<=j;k++) {
sum=sum+d[i-1][j-k];
}
d[i][j]=sum;
}
}
}
System.out.println(d[n-1][m]);
}
}