鸣人的影分身
题目描述:
在火影忍者的世界里,令敌人捉摸不透是非常关键的。我们的主角漩涡鸣人所拥有的一个招数——多重影分身之术——就是一个很好的例子。 影分身是由鸣人身体的查克拉能量制造的,使用的查克拉越多,制造出的影分身越强。 针对不同的作战情况,鸣人可以选择制造出各种强度的影分身,有的用来佯攻,有的用来发起致命一击。 那么问题来了,假设鸣人的查克拉能量为M,他影分身的个数为N,那么制造影分身时有多少种(用K表示)不同的分配方法?(影分身可以被分配到0点查克拉能量).答案不考虑顺序。
输入:
第一行是测试数据的数目t(0 <= t <= 20)。以下每行均包含二个整数M和N,以空格分开。1 <= M,N <= 10。
输出:
输出为一行,包含两个整数:C,R,分别表示最多收服C个小精灵,以及收服C个小精灵时皮卡丘的剩余体力值最多为R。
样例输入:
1 7 3
样例输出:
8
思路:
此题既可用递归做,也可用动态规划做(我用的dp)。
此题可以转化为分苹果,大致题意为:m个苹果,分到n个盘子,有多少种分法?
然后第一层循环枚举每一种有多少个苹果(查克拉),第二层从一开始枚举盘子量(影分身)
如果i<j的话,说明苹果没有盘子多,那么也就是有一些盘子是空的,并且1 0 1与 1 1 0是同一种,所以
dp[i][j] = dp[i][j-1];//(相当于可以减少一个划分数)
下面判断,i>=j,说明每个盘子不存在装不满的情况,那么可以将每个数-1,得到的状态转移方程式即是:
if(i>=j){ dp[i][j] += dp[i-j][j]; }
最后直接输出dp[m][n]即可。
(都到这里了,还不简单???)
代~~码~~:
#include <bits/stdc++.h> using namespace std; int t,m,n; int dp[25][25]; int main(){ scanf("%d",&t); for (int i=1;i<=t;i++){//t组数据 scanf("%d%d",&m,&n); dp[0][0] = 1;//边界 for (int i = 0; i <= m; i++){//枚举查克拉 for (int j = 1; j <= n; j++){//枚举影分身量 dp[i][j] = dp[i][j-1]; //序列中有影分身是空的,那么f[i][j]=f[i][j-1](相当于可以减少一个划分数) if(i>=j){ dp[i][j] += dp[i-j][j]; }//序列数不存在空的影分身,那么可以将每个数减一,得到的该序列的方案数f[i][j]=f[i-j][j](i>=j) } } printf("%d\n",dp[m][n]);//输出 } return 0; }
本文来自博客园,作者:XDFZ武斌,转载请注明原文链接:https://www.cnblogs.com/XDFZwb1523/p/15941016.html

浙公网安备 33010602011771号