蒜頭君走迷宮 組合計數

關鍵:

用公式inv[i]=(modmod/i)inv[mod%i]%modinv[i] = (mod-mod/i)inv[mod\% i]\%mod來線性預處理逆元。

#include<bits/stdc++.h>
using namespace std;
const long long int mod = 1e9 + 7;
long long int Rank[200000]; //rank 和系統命名衝突 
long long int inv[100001];
long long int invRank[100001];
void init(){
	Rank[0] = Rank[1] = 1; //計算階乘 
	for(int i=2;i<200000;i++){
		Rank[i] = (Rank[i-1]*i)%mod;
	}
	inv[1] = 1; 
	for(int i=2;i<100000;i++){ //計算逆元 
	        inv[i]=((mod-mod/i)*inv[mod%i])%mod;//or inv[i]=(mod-(mod/i*inv[mod%i])%mod)%mod;	
	} 
	invRank[0]=invRank[1]=1; 
	for(int i=2;i<100000;i++){
		invRank[i] = (invRank[i-1]*inv[i])%mod;
	}	
}
int main(){
	int n,m; 
	init();
	while(cin>>n>>m){
//		cout<<rank[n+m-2]<<" "<<invRank[n-1]<<" "<<invRank[m-1]<<endl; 
	cout<<Rank[n+m-2]*invRank[n-1]%mod*invRank[m-1]%mod<<'\n';	
	}
    return 0;
}

參考:
線性求逆元及其過程(有瑕疵,大體思路明確)
代碼參考(寫的很好,思路明確)

錯誤範例:動態規劃——>超時

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define MAX_N 100001
const int mod = 1e9 + 7;
long long int C[2][MAX_N];

int main() {
	int n,m; 
	while(cin>>n>>m){
		for(int t=1;t<=m;t++){
			C[0][t] = 1;	
		}
		for(int i =n-1;i>=1;i--){
			C[1][m] =1;
			for(int j=m-1;j>=1;j--){
				C[1][j]=(C[1][j+1]%mod+C[0][j]%mod)%mod;
			}
		for(int t=1;t<=m;t++){
			C[0][t]=C[1][t];
		}
		} 
	cout<<C[0][1]<<'\n';	
	}
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章