題意:求在n棵樹上摘不超過m顆豆子的方案數,結果對p取膜。
思路:其實就相當於把i(0 <= i <= m)個球放入n個不同的盒子裡,盒子可以為空。
很明顯,需要用到隔板法。所以對於i個球,方案數為c(i+n-1, n-1)。
總方案數為c(n-1, n-1)+c(n, n-1)+...+c(n+m-1, n-1);
然後根據公式c(n, m) = c(n, n-m)得方案數為
c(n-1, 0)+c(n, 1)+...+c(n+m-1, m);
然後再根據公式c(n, m) = c(n-1, m)+c(n-1, m-1)得方案數為
0+c(n-1, 0)+c(n, 1)+...+c(n+m-1, m)
= c(n, 0)+c(n, 1)+c(n+1, 2)+...+c(n+m-1, m)
= c(n+m, m)
此時方案數變為了c(n+m, m)%p;
由於n+m和m較大,且p比n+m和m小,且p為素數,所以這兒用lucas定理求解即可。
code1:
#include #define ll long long
using namespace std;
int n, m, p;
ll quickm(ll a, ll b, ll p)
return ans;
}ll c(ll n, ll m, ll p)
return fta*quickm(ftb, p-2, p)%p;
}ll lucas(ll n, ll m, ll p)
return ans;
}int main()
return 0;
}
然後還寫了乙份預處理階乘逆元的,會tle,每次都需要重新計算,而且預處理版的對於lucas寫起來也很難看,lucas以後就像上面寫吧,效率頗好。
code2:
#include #define ll long long
using namespace std;
const int maxn = 100000;
int n, m, p;
ll fact[maxn+5], fiv[maxn+5], inv[maxn+5];
void init()
}ll lucas(ll n, ll m, ll p)
return ans;
}int main()
return 0;
}
繼續加油~
hdu 3037 插板法組合 lucas定理
插板法解決的問題 a1 a2 a3 an m 如果a i 必須是正整數,cn 1m 1 如果a i 是非負數,先強制選 1 轉化為正整數cn 1m 1 n擴充套件,對於每個數最小為多少都可以通過先強行加減的方法把它轉化為,正整數問題。lucas定理 解決cm n mo d 的計算。本題就是插板法列出...
組合數 隔板法
隔板法是組合數學的一種重要思想 一般表現形式為把m個物品放入n個盒子裡 n m letax壞了tat 每個盒子裡必須有至少乙個物品 所有物品完全相同 求方案數 可以在邏輯上將物品放入乙個一維的長盒子裡 然後在任意兩個物品之間插入隔板 那麼我們可以將問題簡化為在m 1個空位中插入n 1個隔板 從而將物...
組合數學 隔板法
隔板法在排列組合中的應用技巧 張紅兵在排列組合中,對於將不可分辨的球裝入到可以分辨的盒子中而求裝入方法數的問題,常用隔板法。例1.求方程的正整數解的個數。分析 將10 個球排成一排,球與球之間形成 9個空隙,將兩個隔板插入這些空隙中 每空至多插一塊隔板 規定由隔板分成的左 中 右三部分的球數分別為x...