小王是大一的学生,想在寒假里强化一下微积分课程的学习,他从图书馆借了一套吉米多维奇的数学分析习题集。他决定在以后的n天里要做完上面的S道积分题。
为了能够尽快地完成任务,小王强迫自己第i天至少要做ai道积分题。但是,小王在假期里还有其他事情(例如过春节),每天的题量不能太多,他估计了一下,第i天做的积分题不能超过bi(bi>=ai)道。
现在小王想知道,究竟能有多少种方案能够在n天里做完这S道习题呢?小王请你写个程序帮他算一算。
具体来说,一个方案就是每天做的微积分题的数目的序列,假设第i天完成xi道题(xi当然满足ai<=i<=bi,且X1+X2+……+Xn=S)。那么向量(X1,X2,…,Xn)就对应了一个方案。两个方案不同是指他们对应的向量不同。
【输入】
一共n+1行,第一行是两个整数n和S,用空格分开,分别表示天数和题目数(1<=n<=20,1<=S<=1000);接下来n行每行两个整数,之间用空格隔开,分别表示第i天对做题数量的限制ai和bi(0<=ai<=bi<=S)。
【输出】
一个整数,表示满足的条件的方案数T.
【输入输出】
| 样例A | 样例B | 样例C | 样例D |
输入样例 | 3 11 2 5 1 6 3 4 | 8 20 1 4 2 8 1 5 2 7 4 7 2 5 2 8 1 3 | 10 55 0 1 0 2 0 3 0 4 0 5 0 8 0 8 0 8 0 9 0 10 | 15 123 1 100 2 100 3 100 4 100 5 100 6 100 7 100 8 100 9 100 10 100 11 100 12 100 13 100 14 100 15 100 |
输出样例 | 8 | 731 | 209 | 680 |
解答:
static class Program
{
static void Main()
{
Console.WriteLine( " Result: " + Calc());
Console.Read();
}
static int Calc()
{
int n, s, count = 0 , lineCount = 0 ;
string [] ns = Console.ReadLine().Split( ' ' );
n = int .Parse(ns[ 0 ]);
s = int .Parse(ns[ 1 ]);
int [,] ai = new int [n, 3 ];
while (lineCount < n)
{
string [] aibi = Console.ReadLine().Split( ' ' );
ai[lineCount, 0 ] = int .Parse(aibi[ 0 ]);
ai[lineCount, 1 ] = int .Parse(aibi[ 1 ]);
ai[lineCount, 2 ] = ai[lineCount, 0 ];
lineCount ++ ;
}
Console.WriteLine( " Wait... " );
while ( true )
{
int sum = 0 ;
for ( int i = 0 ; i < n; i ++ )sum += ai[i, 2 ];
if (sum == s)count ++ ;
for ( int i = n - 1 ; i >= 0 ; i -- )
{
if (ai[i, 2 ] < ai[i, 1 ])
{
ai[i, 2 ] ++ ;
break ;
}
else
{
ai[i, 2 ] = ai[i, 0 ];
if (i == 0 ) return count;
}
}
}
}
}