POJ-1664

 

放苹果

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 30213   Accepted: 19053

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

本题可以看成典型的整数分解问题。将m个苹果放到n个盘子里时可以分为两种情况,我们设a(m,n)表示结果总数,当全部n个盘子都不为0时,即每个盘子至少有一个苹果,这时我们可以将总数看为a(m-n,n);当有一个空盘时,可以看做m个苹果放入n-1个盘子中,即a(m,n-1)(无需考虑多个空盘的情况,递归时自然会出现)。这时我们可得方程a(m,n)=a(m,n-1)+a(m-n,n)。下面我们来讨论几种特殊情况,首先就是m为1/0和n为1/0的情况,显而易见,a(m,1)、a(m,0)、a(1,n)、a(0,n)的结果皆为1。其次就是m<n时,a(m,n)的结果与a(m,m)的结果相同,故当m<n时,a(m,n)=a(m,m)。

我们也可以这样理解a(m,n-1)加一个空盘0即为a(m,n)含0的情况,a(m-n,n)在每一个盘子里加1个苹果即为a(m,n)且不会影响结果,这就是不含0的情况。所以a(m,n-1)和a(m-n,n)组成了a(m,n)即a(m,n)=a(m,n-1)+a(m-n,n)。

附AC代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6
 7 const int MAX=12;
 8
 9 int a[MAX][MAX];
10
11 int main(){
12     int i,j,t,m,n;
13     for(i=0;i<MAX;i++){
14         a[0][i]=1;
15         a[1][i]=1;
16         a[i][0]=1;
17         a[i][1]=1;
18     }
19     for(i=2;i<MAX;i++){
20         for(j=2;j<MAX;j++){
21             if(i>=j)
22             a[i][j]=a[i][j-1]+a[i-j][j];
23             else
24             a[i][j]=a[i][i];
25         }
26     }
27     while(~scanf("%d",&t)){
28         while(t--){
29             scanf("%d %d",&m,&n);
30             if(m>=n)
31             printf("%d\n",a[m][n]);
32             else
33             printf("%d\n",a[m][m]);
34         }
35     }    return 0;
36 }
时间: 2024-10-08 22:43:02

POJ-1664的相关文章

[ACM] POJ 1664 放苹果(n个相同小球放入m个相同盒子)

放苹果 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 25952   Accepted: 16509 Description 把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法. Input 第一行是测试数据的数目t(0 <= t <= 20).以下每行均包含二个整数M和N,以空格分开.1<=M,N<=10. Output 对

递推(三):POJ中的三道递推例题POJ 1664、POJ 2247和POJ 1338

[例9]放苹果(POJ 1664) 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 (1)编程思路. 设f[m]

poj 1664 put apples

题目链接:http://poj.org/problem?id=1664 思路: 数据较小,考虑深度优先搜索搜索解空间. 代码: #include <iostream> using namespace std; int M, N, Count = 0; void dfs( int deep, int x, int put ) { if ( deep == N ) { if ( put == M ) Count++; else return; } else { for ( int i = x; i

poj 1664 放苹果 递归

题目链接: http://poj.org/problem?id=1664 题目描述: 有n个苹果,m个盒子,盒子和苹果都没有顺序,盒子可以为空,问:有多少种放置方式? 解题思路: 当前有n个苹果,m个盒子. (1):假设当前最少的盒子放置一个苹果,则给m个盒子分别放一个苹果,剩下n-m个苹果. (2):假设当前最少的盒子不放苹果,则剩m-1个box,n个苹果. 代码: 1 #include <cstdio> 2 #include <cstring> 3 #include <c

POJ 1664 放苹果 (递推)

题目链接:http://poj.org/problem?id=1664 dp[i][j]表示i个盘放j个苹果的方案数,dp[i][j] 可以由 dp[i - 1][j] 和 dp[i][j - i] 递推而来. 当盘子的个数大于等于苹果的个数: dp[i - 1][j] :i - 1个盘子放j个苹果,说明i个盘子里最少有一个盘子是空的 dp[i][j - i] :i个盘子都放了苹果,说明有j - i个苹果是随便放置的 否则: dp[i][j] = dp[i - 1][j] 然后没有苹果的盘子的方

poj 1664 把平果

这个问题可分为两个子问题:什么时候m<n时刻,例如3苹果放在4阿菜,和3苹果放3一样的. 所以m<n时,f[m][n]=f[m][m]; 当m>=n时.可分为两种放法,一种为至少有一个盘子为空,则有f[m][n-1]种放法. 另外为n个盘子都不为空,则先将n个苹果一个一个放入n的盘子中,剩下的m-n个苹果再放入n个盘子中. 此放法就相当于m-n个苹果放n个盘子里面,有f[m-n][n]种放法. 所以状态转移方程为f[i][j]:if(i>=j)f[i][j]=f[i][j-1]+f

POJ 1664 放苹果

传送门:https://i.cnblogs.com/EditPosts.aspx?opt=1 解题思路: m:苹果数量,n:盘子数量. f(m,n):=m个苹果放在n个盘子的方案数 1.n>m 这时总会有有n-m个盘子剩下,这时问题就可以转换到  f(m,m) 2. n<=m 这时有两种情况,每个盘子都放,然后就是把m-n个苹果放入n个盘子  f(m-n,n); 至少有一个盘子不放,那么就是把m个苹果放入n-1个盘子f(m,n-1); 基本情况 只有1个苹果,或0个苹果只有一种情况. 只有一个

POJ 1664 把苹果

 把苹果 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 25785   Accepted: 16403 Description 把M个相同的苹果放在N个相同的盘子里,同意有的盘子空着不放,问共同拥有多少种不同的分法?(用K表示)5,1,1和1.5,1 是同一种分法. Input 第一行是測试数据的数目t(0 <= t <= 20).下面每行均包括二个整数M和N,以空格分开.1<=M,N<=10. Out

poj 1664 放苹果(dfs)

放苹果 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 30284   Accepted: 19098 Description 把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法. Input 第一行是测试数据的数目t(0 <= t <= 20).以下每行均包含二个整数M和N,以空格分开.1<=M,N<=10. Output 对

poj 1664 放平果

此问题可分为两个子问题:当m<n时,如3个苹果放入4个盘子中,和3个苹果放3个盘子的方法数是一样的. 所以m<n时,f[m][n]=f[m][m]; 当m>=n时,可分为两种放法,一种为至少有一个盘子为空,则有f[m][n-1]种放法. 另外为n个盘子都不为空,则先将n个苹果一个一个放入n的盘子中,剩下的m-n个苹果再放入n个盘子中.此放法就相当于m-n个苹果放n个盘子里面,有f[m-n][n]种放法. 所以状态转移方程为f[i][j]:if(i>=j)f[i][j]=f[i][j