问题描述
小强在玩扑克牌,扑克牌(去掉大小王)是由数字1-13各四种花色组成的。但是小强觉得只有52张牌并不快乐,于是他决定创造一种牛牌,牛牌是由数字1-n各四种花色组成的,但是小强手上只有一只黑色水笔,画不出四种不同的花色,因此他只能创造出数字1ーn各四张牌。现在小强想知道,当他手上有m张牌时,这m张牌一共有多少种牌型。(两种牌型不同当目仅当某个数字在两种牌型中的数量不同)
1≤m≤1000
1≤n≤1000
答案需要对1000000007取模
样例
例1:
输入:n=3,m=2
输出:6
解释:当n=3时,牌堆有1,2,3种类型的牌各四张。
手牌可能的方案为:[1,1],[2,2],[3,3],[1,2],[1,3],[2,3]。总共有6种。所以返回6。
例2:
输入:n=4,m=2
输出:10
解释: 手牌可能的方案为:[1,1],[2,2],[3,3],[4,4],[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]。
解决方法
这个问题的解决方法与背包问题(Knapsack problem)动态规划算法的解决方法类似.
背包问题:
我们有n种物品,物品j的重量为wj,价格为pj
我们假定所有物品的重量和价格都是非负的。背包所能承受的最大重量为W。
如果限定每种物品只能选择0个或1个,则问题称为0-1背包问题。
因此可以将牛牌问题描述成这样:
物品种类为N种,背包容量为M,每一种物品最多可以选四个(也可以不选),选择方案有多少种?
DP解法:
1.首先设置状态矩阵 dp[i] [j] 为当物品种类为i, 背包容量为j时的选择方案.
2. 找到状态转移方程: dp[i] [j]= dp[i-1] [j] + sum(dp[i-1] [j-k]) k的范围为0~4.
也就是说,当背包数量j不发生改变,物品种类的数量+1(从dp[i-1] [j]到dp[i] [j]),
方案的数量增加了sum(dp[i-1] [j-k]),第i类物品在背包的数量有5种可能,0,1,2,3,4.
代码
// An highlighted block
ublic class Solution {
/**
* @param n: 牌的种类为n
* @param m: 持牌人持牌的数量为m
* @return: 牛牌的方案的数量
*/