题目描述
在火影忍者的世界里,令敌人捉摸不透是非常关键的。
我们的主角漩涡鸣人所拥有的一个招数——多重影分身之术——就是一个很好的例子。
影分身是由鸣人身体的查克拉能量制造的,使用的查克拉越多,制造出的影分身越强。
针对不同的作战情况,鸣人可以选择制造出各种强度的影分身,有的用来佯攻,有的用来发起致命一击。
那么问题来了,假设鸣人的查克拉能量为 M,他影分身的个数最多为 N,那么制造影分身时有多少种不同的分配方法?
注意:
影分身可以分配0点能量。
分配方案不考虑顺序,例如:M=7,N=3,那么 (2,2,3) 和 (2,3,2) 被视为同一种方案。
输入格式
第一行是测试数据的数目 t。
以下每行均包含二个整数 M 和 N,以空格分开。
输出格式
对输入的每组数据 M 和 N,用一行输出分配的方法数。
数据范围
0≤t≤20,
1≤M,N≤10
样例
输入样例:
1
7 3
输出样例:
8
算法1 DP
我的思路可能跟大家经常看到的DP解法不一样,- -我也不是很确定我的是否是对的还是蒙对的,如果错了请指正。
装苹果,一个完全背包的问题,这个问题跟整数的拆分很类似
状态表示:f[i][j] 表示只用前i个盘子放j个苹果的所有方法
属性:选法的数量和
状态计算:
第i个盘子放多少个,可以放0,1,2,3,4....j-i个,因为我的思路是从第1个盘子放到第n个盘子,如果你要放到第n个盘子
那么你前面至少要放掉n-1个苹果才可以放到第n个盘子,即之前每个盘子上面都有一个苹果
f[i][j] = f[i-1][j]+ f[i-1][j-1] + f[i-1][j-2] + .......+f[i-1][j-i];
f[i][j-1] = + f[i-1][j-1] + f[i-1][j-2] + f[i-1][j-2] +......+f[i-1][j-i];
那么f[i][j] = f[i-1][j] + f[i][j-1];
时间复杂度
O(nm)
算法基础班的DP分析法
C++ 代码
#include <bits/stdc++.h>
using namespace std;
const int maxn = 25;
int f[maxn];
int main() {
int n,m; // n是盘子,m是苹果数量
while(cin>>m>>n) {
f[0] = 1;
for(int i=1;i<=m;i++) f[i] = 0; // 初始化
for(int i=1; i<=n; i++) { // 遍历盘子
for(int j=i; j<=m; j++) { // 从i到m放苹果
f[j] = f[j] + f[j-i];
}
}
cout<<f[m]<<endl;
}
}