题目描述:
https://www.lintcode.com/problem/bull-cards/description
解答思路:
属于背包的变体,目标函数是方案数(需要不同分支累加)而不是最大收益(需要不同分支取max),每个物品可取0~4个。设为遍历到第i个牌之后,容量为j的解决方案数,则递推式如下(需要注意 j-k的非负性质,k=1,2,3,4):
初始化:
输出:
代码:
#define MOD 1000000007
class Solution {
public:
/**
* @param n: the number
* @param m: the number of cards in hand
* @return: the number of different types of cards
*/
int bullCards(int n, int m) {
// Write your code here.
if (m > 4 * n) {
return 0;
}
std::vector<vector<int>> dp(n + 1);
for (int i = 0; i <= n; i++) {
dp[i].resize(m + 1);
}
InitDp(dp, n, m);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
dp[i][j] = dp[i - 1][j];
for (int k = 1; k <= 4; k++) {
if (j - k >= 0) {
dp[i][j] = (dp[i][j] + dp[i - 1][j - k]) % MOD;
}
}
}
}
return dp[n][m];
}
private:
void InitDp(vector<vector<int>> &dp, int n, int m)
{
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= m; j++) {
dp[i][j] = 0;
}
}
for (int i = 0; i <= n; i++) {
dp[i][0] = 1;
}
}
};