[POJ1664] 放苹果 (动态规划,组合数学)

题目描述

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

输入输出格式

输入格式:

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

输出格式:

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

输入输出样例

输入样例#1:

1
7 3

输出样例#1:

8

输入样例#2:

3
3 2
4 3
2 7

输出样例#2:

2
4
2

Solution

这道题是我做 P1655 的时候看到的,似乎又是一道DP来解组合数学.

状态很好定义:
\[ f[i][j]\]
表示当前有 i 个苹果,放了 j 个箱子的方案数.

初始化:
1)只有当没箱子或者没苹果的时候我们才赋成0
2)当没有苹果,只有一只箱子的时候,我们赋为1,此时只有一种情况.就是不放


前导状态
1)可以有多个箱子不放,此处通过递归来实现
2)全部都放,所以需要m个苹果来每一层至少垫上一个,然后又剩下n-m个苹果随意放

转移方程:
\[f[i][j]=f[i][j-1]+f[i-j][j]\]

代码

#include<bits/stdc++.h>
using namespace std;
int t;

int dp(int n,int m)
{
    if(n<0||m<1)return 0;
    if(n==0&&m==1)return 1;
    return dp(n,m-1)+dp(n-m,m);
}

int main()
{
    ios::sync_with_stdio(false);
    cin>>t;
    while(t--)
    {
        int n,m;
        cin>>n>>m;
        cout<<dp(n,m)<<endl;
    }
}

...






当然了,作为一道组合类的题目,也可以直接作为一道生成函数的模板题来做.但是我似乎没打,只给出一个网址,日后会补生成函数的.
https://blog.csdn.net/dlutjwh/article/details/69217270

猜你喜欢

转载自www.cnblogs.com/Kv-Stalin/p/9113833.html