1. 程式人生 > >2566 統計硬幣(常數時間解法)

2566 統計硬幣(常數時間解法)

題目:

Description

假設一堆由1分、2分、5分組成的n個硬幣總面值為m分,求一共有多少種可能的組合方式(某種面值的硬幣可以數量可以為0)。

Input

輸入資料第一行有一個正整數T,表示有T組測試資料; 
接下來的T行,每行有兩個數n,m,n和m的含義同上。 

Output

對於每組測試資料,請輸出可能的組合方式數; 
每組輸出佔一行。 

Sample Input

2
3 5
4 8

Sample Output

1
2

首先判斷n*5>=m是否成立,如果不成立的話,方案數就是0了

如果n*5>=m,那麼5分硬幣的數量可能是0,1,2......m/5

假設5分硬幣的數目是i,0<=i<=m/5

那麼現在就是考慮,n-i個1分和2分的硬幣組成m-i*5分有多少種方案?

規律很簡單,如果n-i<=m-i*5<=(n-i)*2那麼方案數為1,否則為0

綜上所述,如果n*5<m那麼方案數為0,否則,方案數是閉區間[0,m/5]和閉區間[(m-n*2)/3.0,m-n/4]的交集所包含的整數的數量,之間用交集的上界減下界即可。

程式碼:

#include <iostream>
using namespacestd;

int f(int n, int m)
{
	if (n * 5 < m || m < n)return
0; int up = n * 5, down = 0; if ((m - n) / 4 < up)up = (m - n) / 4; if ((m - n * 2) >= 3)down = (m - n * 2 + 2) / 3; return up-down+1; } int main() { int t, n, m; cin >> t; while (t--) { cin >> n >> m; cout << f(n, m) << endl; } return 0; }

程式碼AC了的,不用懷疑。