dp演算法求組合數
中學就學過排列,組合 ,比如 c5,2 = 10; c6,2 = 15
如果用演算法實現的話,難道也要先做一連串的乘法,然後再相除嗎? 比如: c5,2 = (5*4*3*2)/(3*2)
如果數很大的話,又是乘又做除的,多牛的計算機才能搞定呢?
先看看簡單的:
2個數選2個,共有1種方法
3個數選2個,共有3種方法
4個數選2個,共有6種方法
n個數選2個,共有多少種方法?
f(n,2) = f(n-1,2) + f(n-1,1) //這樣寫看的更清楚些.
那麼m個數選n出來,有多少種選擇呢?
f(m,n) = f(m-1,n) + f(m-1,n-1)
到此處,dp的遞迴解空間已經出來了.
f(m,n) = 1 n=0 or m=0 or n=m
f(m,n) = m n=1
f(m,n) = f(m-1,n) + f(m-1,n-1) m!=n 當然m>n
剩下的工作就是程式實現了.但是還有個小問題,就是在dp迭代的過程中是否需要記憶.在這個演算法當然需要記憶.
實現的過程中,可以做些小優化,比如m=5 n=3 可以求c5,2的組合數就是要少遞迴幾次.
#include "stdafx.h"
#include
using namespace std;
__int64 aug[200][200] = ;
__int64 getcomposite(int m,int n)
return aug[m-1][n] + aug[m-1][n-1];
}
int main()
/**/
組合數學 求組合數
對於求組合數,要根據所給資料範圍來選擇合適的演算法 這道題中所給的資料範圍適合用打表的方法直接暴力求解 先用4e6的複雜度預處理出所有的情況,再用1e4的複雜度完成詢問即可 include using namespace std const int n 2010 const int mod 1e9 ...
組合數 dp 運
問題 b 運 時間限制 1 sec 記憶體限制 128 mb 問題背景 zhx 和妹子們玩數數遊戲。問題描述 僅包含4或7的數被稱為幸運數。乙個序列的子串行被定義為從序列中刪去若干個數,剩下的數組成的新序列。兩個子串行被定義為不同的當且僅當其中的元素在原始序列中的下標的集合不相等。對於乙個長度為 n...
組合數 dp 運
問題 b 運 時間限制 1 sec 記憶體限制 128 mb 問題背景 zhx 和妹子們玩數數遊戲。問題描述 僅包含4或7的數被稱為幸運數。乙個序列的子串行被定義為從序列中刪去若干個數,剩下的數組成的新序列。兩個子串行被定義為不同的當且僅當其中的元素在原始序列中的下標的集合不相等。對於乙個長度為 n...