dfs 放苹果

Description

把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。

Input

第一行是测试数据的数目t(0 <= t <= 20)。以下每行均包含二个整数M和N,以空格分开。1<=M,N<=10。

Output

对输入的每组数据M和N,用一行输出相应的K。

Sample Input

1
7 3

Sample Output

8

代码:
 

#include<cstdio>
#include<algorithm>
using namespace std;
int m,n;
int ans;//最终解
void dfs(int cnt,int left,int num)//当前已放cnt个盘子,还剩left个苹果且上把放了num个苹果,从多往少放
{
    if(cnt==n&&left==0) {ans++;return;}
   // if(left==0)return; //去掉没有用完盘子的情况。
    else if(left==0) ans++;
    else for(int i = min(num, left); i >= (left-1)/(n-cnt)+1; i--)//left>0时
/*

    其中i表示当前盘子将要放的苹果数,既然上一个盘子放了num个苹果,i肯定要<=num了,
且剩余left个苹果,所以i初值= min(num, left) 表示i能取到的最大值。

       但是i能取的最小值是多少呢?i能直接取0吗?如果left>0的话,
i不能取0。因为如果这个i取0,后面的盘子都得为0,当前剩余的left个苹果就没地方放了。
left不为0时,i能取的最少值为:上取整(剩余苹果数/剩余盘子数)也就是(left-1)/(n-cnt)+1。
注意这里要求left>=1。

*/
        dfs(cnt+1,left-i,i);
}
int main()
{
    int T; scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&m,&n);
        ans=0;
        dfs(0,m,100000);
        printf("%d\n",ans);
    }
    return 0;
}

变换:盘子必须用完:
代码:
 

#include<cstdio>
#include<algorithm>
using namespace std;
int m,n;
int ans;//最终解
void dfs(int cnt,int left,int num)//当前已放cnt个盘子,还剩left个苹果且上把放了num个苹果,从多往少放
{
    if(cnt==n&&left==0) {ans++;return;}
    if(left==0)return; //去掉没有用完盘子的情况。
   // else if(left==0) ans++;
    else for(int i = min(num, left); i >= (left-1)/(n-cnt)+1; i--)//left>0时
        dfs(cnt+1,left-i,i);
}
int main()
{
    int T; scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&m,&n);
        ans=0;
        dfs(0,m,100000);
        printf("%d\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40859951/article/details/84645944