Bailian1664 Placing apples【递推+记忆化递归】

1664:Placing apples
总时间限制: 1000ms 内存限制: 65536kB
描述
We are going to place M same apples into N same plates.
There could be some empty plates.
How many methods do we have?
When we have 7 applesand 3 plates, the methods, (1, 5, 1) and (5, 1, 1) are the same.
输入
The first line is the number of test cases, t. 0<=t<=20
The next t lines are test cases containing two numbers, M and N. 1<=M, N<=10.
输出
Output the numbers of method in each test case in one line.
样例输入
1
7 3
样例输出
8

问题链接Bailian1664 Placing apples
问题描述:(略)
问题分析
????这个问题的关键是递推函数。
m个苹果放在n个盘子中,那么定义函数为apple(m,n):
1.m=0,没有苹果,那么只有一种放法,即apple(0,n)=1
2.n=1,只有一个盘中,不论有或者无苹果,那么只有一种放法,apple(m,1)=1
3.n>m,和m个苹果放在m个盘子中是一样的,即apple(m,n)=apple(m,m)
4.m>=n,这时分为两种情况,一是所有盘子都有苹果,二是不是所有盘子都有苹果。不是所有盘子都有苹果和至少有一个盘子空着是一样的,即=apple(m,n-1)。所有盘子都有苹果,也就是至少每个盘子有一个苹果,m个苹果中的n个放在n个盘子中,剩下的m-n个苹果,这和m-n个苹果放在n个盘子中是是一样的,即=apple(m-n, n)。这时,apple(m,n)=apple(m-n, n)+apple(m,n-1)。
????本题采用记忆化递归的解法。
????这个题也可以用母函数来解,是一个母函数的裸题。
程序说明
????本题与参考链接是同一题,使用参考链接的程序提交就AC了。
参考链接POJ1664 放苹果【递推+记忆化递归】
题记:朋友交多了,容易遇见熟人。

AC的C语言程序如下:

/* POJ1664 放苹果 */

#include <stdio.h>
#include <string.h>

#define N 10
int a[N + 1][N + 1];

int apple(int m, int n)
{
    if(a[m][n])
        return a[m][n];
    else {
        if(m == 0 || n == 1)
            return a[m][n] = 1;
        else if(n > m)
            return a[m][n] = apple(m, m);
        else
            return a[m][n] = apple(m - n, n) + apple(m, n - 1);
    }
}

int main(void)
{
    memset(a, 0, sizeof(a));

    int t, m, n;
    scanf("%d", &t);
    while(t--) {
        scanf("%d%d", &m, &n);

        printf("%d\n", apple(m, n));
    }

    return 0;
}

原文地址:https://www.cnblogs.com/tigerisland45/p/10166475.html

时间: 2024-08-01 19:14:28

Bailian1664 Placing apples【递推+记忆化递归】的相关文章

HDU4919 Exclusive or(递推+记忆化搜索+大数)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4919 题意: 给定n求sigma(i^(n - i)) (1<=i<=n-1) 分析: 打表后可以发现规律 1) n = 2 * k + 1; f[n] = 4 * f[k] + 6; 2) n = 2 * k f[n] = 2 * f[k] + 2 * f[k-1] + 4 * k - 4; 具体的证明:http://blog.csdn.net/houserabbit/article/detai

POJ 1579 Function Run Fun 记忆化递归

典型的记忆化递归问题. 这类问题的记忆主要是利用数组记忆.那么已经计算过的值就能够直接返回.不须要进一步递归了. 注意:下标越界.递归顺序不能错,及时推断是否已经计算过值了,不要多递归. 或者直接使用动态规划法填好表也是能够的. #include <stdio.h> #include <limits.h> const int MAX_N = 21; int W[MAX_N][MAX_N][MAX_N]; int getValue(int a, int b, int c) { if

wikioi天梯 1011 数的计算 (记忆化递归)

题目描述 Description 我们要求找出具有下列性质数的个数(包含输入的自然数n): 先输入一个自然数n(n<=1000),然后对此自然数按照如下方法进行处理: 1.          不作任何处理; 2.          在它的左边加上一个自然数,但该自然数不能超过原数的一半; 3.          加上数后,继续按此规则进行处理,直到不能再加自然数为止. 输入描述 Input Description 一个数n 输出描述 Output Description 满足条件的数的个数 样例

第五第六课------递推+记忆话搜索+搜索八皇后(思想是做梦)+各种剪枝思想

搜索是一个漫长的过程贯彻整个oi: 八皇后------- #include <bits/stdc++.h>#define inf 0x7fusing namespace std;int n,ans,a[inf],b[inf],c[inf],d[inf];void print(){ ++ans; if(ans<=3){ for(int i=1;i<=n;i++) cout<<d[i]<<" "; cout<<endl; }} v

数字三角形——递归、递推、记忆化搜索

数字三角形 描述: 有一个由非负整数组成的三角形,第一行只有一个数,除了最下行之外没个数的左下方和右下方各有一个数. 问题: 从第一行的数开始,每次可以往左下或右下走一格,直到走到最下行,把沿途经过的数全部加起来.如何走才能使得这个和尽量大? 分析: 不难看出此题是一个动态的决策问题:每次有两种选择--左下或右下.如果用回溯法求出所有的可能的路线,就可以从中选出最优的路线.但和往常一样,回溯法的效率太低:一个n层数字三角形的完整路线有2^n条,当n很大时回溯法的速度将让人无法忍受.因此本题讨论用

搜索分析(DFS、BFS、递归、记忆化搜索)

搜索分析(DFS.BFS.递归.记忆化搜索) 1.线性查找 在数组a[]={0,1,2,3,4,5,6,7,8,9,10}中查找1这个元素. (1)普通搜索方法,一个循环从0到10搜索,这里略. (2)递归(从中间向两边) 1 //递归一定要写成记忆化递归 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool vis[11]; 5 int count1=0; 6 7 void search(int n){ 8 count1++; 9

P2921 [USACO08DEC]在农场万圣节Trick or Treat on the Farm 记忆化搜索dfs

题目描述 每年,在威斯康星州,奶牛们都会穿上衣服,收集农夫约翰在N(1<=N<=100,000)个牛棚隔间中留下的糖果,以此来庆祝美国秋天的万圣节. 由于牛棚不太大,FJ通过指定奶牛必须遵循的穿越路线来确保奶牛的乐趣.为了实现这个让奶牛在牛棚里来回穿梭的方案,FJ在第i号隔间上张贴了一个“下一个隔间”Next_i(1<=Next_i<=N),告诉奶牛要去的下一个隔间:这样,为了收集它们的糖果,奶牛就会在牛棚里来回穿梭了. FJ命令奶牛i应该从i号隔间开始收集糖果.如果一只奶牛回到某

动态规划 数字三角形(递归,递推,记忆化搜索)

题目要求: 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 在上面的数字三角形中寻找在上面的数字三角形中寻找一条从顶部到底边的路径,使得路径上所经过的数字之和最大.路径上的每一步都只能往左下或右下走.只需要求出这个最大和即可,不必给出具体路径. 三角形的行数大于1小于等于100,数字为 0 - 99 输入格式: 5 //三角形行数.下面是三角形 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 解题思路: 用二维数组存放数字三角形 D[r][j] //表示第i行第j个元素的

动态规划&mdash;&mdash;数字三角形(递归or递推or记忆化搜索)

动态规划的核心就是状态和状态转移方程. 对于该题,需要用抽象的方法思考,把当前的位置(i,j)看成一个状态,然后定义状态的指标函数d(i,j)为从格子出发时能得到的最大和(包括格子本身的值). 在这个状态定义下,原问题的解就是d(i,j). 下面看一下不同状态之间如何转移.从格子(i,j)出发有两种策略.如果向左走,则到(i+1,j)后需要求"从(i+1,j)出发能得到的最大和"这一问题,即d(i+1,j). 类似的,往右走之后需要求解d(i+1,j+1).由于可以在这两个决策中自由选