多重集組合數

2021-10-08 11:11:35 字數 1176 閱讀 7035

題述

有n種物品,第i種物品有ai個。不同種類的物品可以互相區分但相同種類的無法區分。從這些物品中取出m個的話,有多少種取法?求出方案數模m的餘數。

限制條件

1<=n<=1000

1<=m<=1000

1<=ai<=1000

2<=m<=10000

樣例

輸入3 5

1 2 3

10000輸出6

題記

dp[i+1][j]:=從前i種物品中取出j個的組合總數

dp[i+1][j]=dp[i+1][j-1]+dp[i][j]-dp[i][j-1-ai]

怎麼理解呢,其實跟別的dp題差不多,就是第i種物品取和不取兩種情況,但是每種物品可能有多個,所以就涉及到取多少個,這個根據我們做過的題可以想到解決取多少個不需要迴圈,之前的就已經算過我們可以直接用之前儲存的。dp[i+1][j-1]意思就是我們第i個物品至少取1個,也就是當前這一步我要取乙個第i個物品(可能已經取過若干個第i個物品了),這就涉及到另外乙個問題,如果我們這裡的j大於a[i]怎麼辦,那麼我們有可能已經把第i個物品取完了,但是程式不知道啊,它就接著硬著頭皮算,所以我們要減去j大於等於a[i]的部分,保證不會取多,因此需要減去乙個dp[i][j-1-a[i]],dp[i][j-1-a[i]]也就是我前i-1個物品只取走了j-1-a[i],也就是a[i]會被取走超過a[i]的情況,減一下就行了。

**如下

#include

//多重集組合數

using

namespace std;

const

int max=

1005

;//輸入

int m,n;

int a[max]

;int m;

//dp[i+1][j]從前i種物品中取出j個的組合總數

int dp[max]

[max]

;void

solve()

}printf

("%d\n"

,dp[n]

[m]);}

intmain()

多重集組合數

問題描述 有n種物品,第i種物品有ai個。從這些物品中取m個,有多少種取法,求出方案數 模上m的餘數。sample input n 3 m 3 a m 10000 sample output 6 0 0 3,0 1 2,0 2 1,1 0 2,1 1 1,1 2 0 該題採用動態規劃。其中有乙個思想...

多重集組合數問題

參考 題目 有n種物品,第i種物品有a個.不同種類的物品可以互相區分,但相同種類的無法區分.從這些物品中取出m個,有多少種取法?求出數模m的餘數.例如 有n 3種物品,每種a 個,取出m 3個,取法result 6 0 0 3,0 1 2,0 2 1,1 0 2,1 1 1,1 2 0 dp i j...

poj1173 多重集組合數

這道題的本質是將n個物品分成k堆,每堆物品個數大於0小於等於m的方案數。我們定義d i j 為前i堆物品總數為j的方案數,那麼d i j 的求解方法如下 其可化為d i j d i j 1 d i 1 j 1 d i 1 j 1 m 初始條件為d 0 0 1 d i 0 0 i 0 證明如下 對於第...