鸣人的影分身

题目描述:

在火影忍者的世界里,令敌人捉摸不透是非常关键的。我们的主角漩涡鸣人所拥有的一个招数——多重影分身之术——就是一个很好的例子。 影分身是由鸣人身体的查克拉能量制造的,使用的查克拉越多,制造出的影分身越强。 针对不同的作战情况,鸣人可以选择制造出各种强度的影分身,有的用来佯攻,有的用来发起致命一击。 那么问题来了,假设鸣人的查克拉能量为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;
} 

 

posted @ 2022-02-26 23:11  XDFZ武斌  阅读(395)  评论(0)    收藏  举报