LightOJ 1005 - Rooks (組合數學dp模擬)

題目鏈接:http://lightoj.com/volume_showproblem.php?problem=1005


題意:n*n的棋盤上放m個車,問有多少种放車的方式使得每個車都不會互相攻擊到(即每個車都佔有他所在的一行一豎兩條直線)

思路:這道dp模擬的是組合數學的算法( n行中選出m行,C(n,m),再在n列中選出m列隨便放A(n,m),答案爲C(n,m)*A(n,m) 

代碼:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <string>
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#define ll long long

using namespace std;

ll dp[35][35];

void solve()
{
	int i,j;
	memset(dp,0,sizeof(dp));//初始化排除k>n的時候的情況
	for(i=1;i<31;i++){
		dp[i][0]=1;
		dp[i][1]=i*i;
	}
	for(i=2;i<31;i++){
		for(j=2;j<=i;j++)
			dp[i][j]=dp[i][1]*dp[i-1][j-1]/j;//模擬C(n,m)*A(n,m) 
	}
}

int main()
{
	int n,k,t=1,T;
	solve();
	scanf("%d",&T);
	while(T--){
		scanf("%d%d",&n,&k);
		printf("Case %d: %lld\n",t++,dp[n][k]);
	}
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章