楊輝三角(組合數)+排列組合

愚末語發表於2020-11-20

洛谷P2638

一道虐我的數學題,今天太累了,就簡單聊聊思想核心
題目如下:

特斯拉公司的六位密碼被輕鬆破解後,引發了人們對電動車的安全效能的懷疑。李華聽聞後,自己設計了一套密碼:假設安全系統中有n個儲存區,每個儲存區最多能儲存存2個種類不同的訊號(可以不儲存任何訊號)。有0和1這兩種訊號,其中0有a個,1有b個,單獨一個0或1算一個訊號。現要將這些訊號儲存在儲存區中,0和1可以不用全部儲存,一種不同的儲存方案經過李華處理後就將是一串不同的密碼。現在給出n,a,b,求可能的不同儲存方案的個數。

AC程式碼:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define ull unsigned long long
#define N 1000
ull s[N][N];
int main()
{
	ull n, a, b;
	cin >> n >> a >> b;
	for(int i=1;i<=60;i++)
		for (int j = 1; j <= i; j++)
		{
			if (j == 1 || j == i)s[i][j] = 1;
			else
			{
				s[i][j] = s[i - 1][j] + s[i - 1][j - 1];
			}
		}
	ull ans = 0;
	for(int i=0;i<=a;i++)
		for (int j = 0; j <= b; j++)
		{
			ans += s[n + i][n] * s[n + j][n];
		}
	cout << ans << endl;

	return 0;
}

先聊聊楊輝三角,我們有知道楊輝三角是長啥樣的,但都不知到楊輝三角的性質,其中能夠用來解決本題的是:楊輝三角中第 i 行,第 j 列的數就等於 從 i-1 個數中砸出 j-1 個數的方案,也就是C(j-1,i-1)。
當然,僅僅知道概念與性質是不夠的,我們還要用計算機將楊輝三角表達出來。
看到這裡,你肯定在想,這還不簡單?直接雙重迴圈不久可以了嗎?對此,我只想說:you are right! 真就這麼簡單,但是在簡單之下暗藏坑點。因為第 i 行 第 j 列表達的是 C(j-1,i-1)。 途中經過一層轉換,那麼如果不細緻就可能出現錯誤。
比如說,如果你把第一行視為第0 行,第一列視為第0 列,你的程式碼怎麼寫?可以試一試,如果成功了當我沒說,失敗了自然知道我講了什麼。
也在這裡給我做個筆記,寫楊輝三角的時候就從 1 遍歷到 n 行,從 1 遍歷到 m 列。不要想太多東西。


聊回本題思路,只能說數學題真是妙啊!
隔板法 高中數學全還給老師了

我們先退一步。k 個球分給 n 個盒子。我們假設,題目要求變為每個盒子至少要分得一個球,如何解決呢?
k 個球之間形成了 k-1 個間隙,我們將 n-1 個隔板插入間隙中,隔板就將球分為了 k份,符合假設。這樣從 k−1 個間隙中選出 n-1 個插入隔板,再進行計算組合數。
但是現在要解決的情況是盒子可以分不到球。這樣我們通過一步化歸,轉換為上面的情況:新增 n個球,使每個盒子至少有一個球。這樣分完後只要將每個盒子多拿的一個球收回,便回到原情況了。

大佬的思路妙就妙在增添n個隔板上。這樣就可以製造出一個無論什麼情況都可以用C的情況,又不會影響答案的精度。

相關文章