递推(三):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][n]表示把m个苹果放到n个盘子里的不同方法的种数。
1)当盘子数n为1的时候,只有一种放法,就是把所有苹果放到一个盘子里。
2)当苹果数m为1的时候,也只有一种放法,因为盘子之间并无顺序,所以不管这个苹果放在哪个盘子里,结果都算一个。
3)当m<n时,m个苹果最多只能放到m个盘子中去(一个盘子里放一个),盘子有多余的。此时,实际上就相当于把m个苹果放到m个盘子里一样,也就是f[m][m]。
4)当m>=n时,可分两种情况讨论。一种是至少有一个盘子里不放苹果,这就相当于f[m][n-1];另一种是先取出n个苹果一个盘子里放一个,再将剩下的m-n个苹果放到n个盘子里去,即f[m-n][n]。
综上所述,可得到递推关系式如下:
f[m][n]=1 当m=1或n=1时
f[m][n] = f[m][m] 当m<n时
f[m][n] = f[m-n][n] + f[m][n-1] 当m>=n时;
另外,当m=0或n=0时,定义f[m][n]=1。即有盘子没苹果放,或者有苹果没有盘子装,都是一种可能存在的情况。这个可以特殊处理,就像0的阶乘定义为1一样。
(2)源程序。
#include <iostream>
using namespace std;
int main()
{
int f[11][11];
int t,n,m,i,j;
for (i=0;i<=10;i++)
{
f[i][0]=1;
f[i][1]=1;
f[0][i]=1;
f[1][i]=1;
}
for (i=2;i<=10;i++)
for(j=2;j<=10;j++)
{
if(i>=j)
f[i][j]=f[i][j-1]+f[i-j][j];
if(i<j)
f[i][j]=f[i][i];
}
cin>>t;
while(t--)
{
cin>>m>>n;
cout<<f[m][n]<<endl;
}
return 0;
}
【例10】Humble Numbers (POJ 2247)
Description
A number whose only prime factors are 2,3,5 or 7 is called a humble number. The sequence 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 24, 25, 27, shows the first 20 humble numbers.
Write a program to find and print the nth element in this sequence.
Input
The input consists of one or more test cases. Each test case consists of one integer n with 1 <= n <= 5842. Input is terminated by a value of zero (0) for n.
Output
For each test case, print one line saying "The nth humble number is number.". Depending on the value of n, the correct suffix "st", "nd", "rd", or "th" for the ordinal number nth has to be used like it is shown in the sample output.
Sample Input
1
2
3
4
11
21
100
5842
0
Sample Output
The 1st humble number is 1.
The 2nd humble number is 2.
The 3rd humble number is 3.
The 4th humble number is 4.
The 11th humble number is 12.
The 21st humble number is 28.
The 100th humble number is 450.
The 5842nd humble number is 2000000000.
(1)编程思路。
根据数列的定义,数列中的一个数应该是其前面某个数乘以2、3、5或者7的结果。因此,可以定义一个数组num[5843]来顺序保存数列中的数,数组里面的每一个元素的值是前面的某个元素值乘以2、3、5或者7得到。
问题的关键是怎样确保数组里面的各元素是按值的大小依次生成的。
假设数组中已经有若干个数列中的元素,排好序后存在数组中。把数列中现有的最大的数记做M。由于数列中的下一个数肯定是前面某一个数乘以2、3、5或者7的结果。首先考虑把已有的每个数乘以2。在乘以2的时候,能得到若干个结果小于或等于M的。由于数组中的元素是按照顺序生成的,小于或者等于M的数肯定已经在数组中了,不需再次考虑;还会得到若干个大于M的结果,但只需要第一个大于M的结果,因为数组中的元素是按值从小到大顺序生成的,其他更大的结果可以以后再说,记下得到的第一个乘以2后大于M的数M2。同样,把已有的每一个数乘以3、5和7,记下得到的第一个大于M的结果M3、M5和M7。那么,数列中下一个数应该是M2、M3、M5和M7四个数的最小者。
事实上,上面所说的把数组中已有的每个数分别都乘以2、3、5和7,是不需要的,因为已有的数是按顺序存在数组中的。对乘以2而言,肯定存在某一个数T2,排在它之前的每一个数乘以2得到的结果都会小于已有最大的数,在它之后的每一个数乘以2得到的结果都会太大。因此,只需要记下这个数的位置P2,同时每次生成一个新的数列中的数的时候,去更新这个P2。对乘以3、5和7而言,存在着同样的P3、P5和P7。
定义变量index保存当前待生成的数在数列中的序号,显然,已生成的数列中的最大元素为Num[curIndex-1]。
定义4个指针变量int *p2,*p3,*p5,*p7;分别指向数组中的4个元素,排在所指元素之前的每一个数乘以2(或3、或5、或7)得到的结果都会小于已有最大的数num[index-1],在所指元素之后的每一个数乘以2(或3、或5、或7)得到的结果都会太大。
初始时,num[1] = 1、index =2、p2 = p3 = p5 = &num[1]。
生成第index个元素的方法为:
if (*p2 * 2<*p3 * 3) min = *p2 * 2;
else min= *p3 * 3;
if (min> *p5 * 5) min=*p5 * 5;
if (min> *p7 *7) min=*p7 * 7;
num[index] = min;
第index个元素生成后,需要对指针p2、p3、p5和p7进行更新,更新方法为:
if(num[index]==*p2*2) p2++;
if(num[index]==*p3*3) p3++;
if(num[index]==*p5*5) p5++;
if(num[index]==*p7*7) p7++;
(2)源程序。
#include<iostream>
using namespace std;
int main()
{
int num[5843],index,min,n;
int *p2,*p3,*p5,*p7;
p2=p3=p5=p7=&num[1];
num[1]=1;
for(index=2;index<=5842;index++)
{
if (*p2 * 2<*p3 * 3) min = *p2 * 2;
else min= *p3 * 3;
if (min> *p5 * 5) min=*p5 * 5;
if (min> *p7 *7) min=*p7 * 7;
num[index] = min;
if(num[index]==*p2*2) p2++;
if(num[index]==*p3*3) p3++;
if(num[index]==*p5*5) p5++;
if(num[index]==*p7*7) p7++;
}
while(cin>>n && n!=0)
{
if (n%10 == 1 && n%100 != 11)
cout<<"The "<<n<<"st humble number is "<<num[n]<<"."<<endl;
else if (n%10 == 2 && n%100 != 12)
cout<<"The "<<n<<"nd humble number is "<<num[n]<<"."<<endl;
else if (n%10 == 3 && n%100 != 13)
cout<<"The "<<n<<"rd humble number is "<<num[n]<<"."<<endl;
else
cout<<"The "<<n<<"th humble number is "<<num[n]<<"."<<endl;
}
return 0;
}
【例11】Ugly Numbers (POJ 1338)
Description
Ugly numbers are numbers whose only prime factors are 2, 3 or 5. The sequence
1, 2, 3, 4, 5, 6, 8, 9, 10, 12, ...
shows the first 10 ugly numbers. By convention, 1 is included.
Given the integer n,write a program to find and print the n'th ugly number.
Input
Each line of the input contains a postisive integer n (n <= 1500).Input is terminated by a line with n=0.
Output
For each line, output the n’th ugly number .:Don’t deal with the line with n=0.
Sample Input
1
2
9
0
Sample Output
1
2
10
(1)编程思路。
根据数列的定义,数列中的一个数应该是其前面某个数乘以2、3或者5的结果。因此,可以定义一个数组num[1501]来顺序保存数列中的数,数组里面的每一个元素的值是前面的某个元素值乘以2、3或者5得到。
阅读体会例10中的编程思路,将例10的源程序略作修改即可。
(2)源程序。
#include<iostream>
using namespace std;
int main()
{
int num[1501],index,min,n;
int *p2,*p3,*p5;
p2=p3=p5=&num[1];
num[1]=1;
for (index=2;index<=1500;index++)
{
if (*p2 * 2<*p3 * 3) min = *p2 * 2;
else min= *p3 * 3;
if (min> *p5 * 5) min=*p5 * 5;
num[index] = min;
if(num[index]==*p2*2) p2++;
if(num[index]==*p3*3) p3++;
if(num[index]==*p5*5) p5++;
}
while(cin>>n && n!=0)
{
cout<<num[n]<<endl;
}
return 0;
}
递推(三):POJ中的三道递推例题POJ 1664、POJ 2247和POJ 1338的更多相关文章
- POJ 3734 Blocks 矩阵递推
POJ3734 比较简单的递推题目,只需要记录当前两种颜色均为偶数, 只有一种颜色为偶数 两种颜色都为奇数 三个数量即可,递推方程相信大家可以导出. 最后来个快速幂加速即可. #include< ...
- MVC 中使用 SignalR 实现推送功能
MVC 中使用 SignalR 实现推送功能 一,简介 Signal 是微软支持的一个运行在 Dot NET 平台上的 html websocket 框架.它出现的主要目的是实现服务器主动推送(Pus ...
- 在 Asp.NET MVC 中使用 SignalR 实现推送功能 [转]
在 Asp.NET MVC 中使用 SignalR 实现推送功能 罗朝辉 ( http://blog.csdn.net/kesalin ) CC许可,转载请注明出处 一,简介 Signal 是微软支持 ...
- IOS中程序如何进行推送消息(本地推送,远程推送)
[1]-------------什么是推送消息? 我就以一张图解释------------ [2]-----------IOS程序中如何进行本地推送?----------- 2.1,先征求用户同意 1 ...
- javascript基础程序(算出一个数的平方值、算出一个数的阶乘、输出!- !- !- !- !- -! -! -! -! -! 、函数三个数中的最大数)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- ytu 1061: 从三个数中找出最大的数(水题,模板函数练习 + 宏定义练习)
1061: 从三个数中找出最大的数 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 154 Solved: 124[Submit][Status][We ...
- IOS中程序如何进行推送消息(本地推送,远程推送)2(上)
未看过本地推送的,可以提前看一下本地推送. http://www.cnblogs.com/wolfhous/p/5135711.html =============================== ...
- 求三数中Max和猜拳游戏
方法一: Console.WriteLine("请输入三个数字:"); int a = int.Parse(Console.ReadLine()); int b = int.Par ...
- GoEasy实现web实时推送过程中的自动补发功能
熟悉GoEasy推送的朋友都知道GoEasy推送实现web实时推送并且能够非常准确稳定地将信息推送到客户端.在后台功能中查看接收信息详情时,可有谁注意到有时候在发送记录里有一个红色的R标志?R又代表的 ...
随机推荐
- Code-NFine:jqgrid 数据绑定
ylbtech-Code-NFine:jqgrid 数据绑定 1. jqgrid 基本列展示返回顶部 1. 1.1..cshtml $(function () { gridList(); }) fun ...
- 《SONG FROM PI: A MUSICALLY PLAUSIBLE NETWORK FOR POP MUSIC GENERATION》论文笔记
出处:ICLR 2017 Motivation 提出一个通用的基于RNN的pop music生成模型,在层次结构中封装了先验乐理知识(prior knowledge about how pop mus ...
- centos7安装redis3.2.12
1.准备安装包,放在/usr/local/src/ 2.解压安装包,解压到/usr/local/ tar zxf redis-3.2.12.tar.gz -C /usr/local/ 3.cd /us ...
- 用Python在局域网根据IP地址查找计算机名
1.要使用socket模块 代码如下: import sys, socket # hostname = socket.gethostname()# print("Host name:&quo ...
- hibernate的基础学习
工具类: public class H3Util { private static final SessionFactory sessionFactory = buildSessionFactory( ...
- js实现属性只读
第一种 Object.defineProperty 这种是在vue源码中看见的 let obj = { $data: {} }; Object.defineProperty(obj, '$data', ...
- alternatives 命令学习
最经在捣鼓Cloudera的cdh ,发现里面使用了alternatives命令,由于不懂这个命令,让我走了好多弯路. 现在mark一下 ubuntu 12.04 系统的命令为:update-alte ...
- P1223 [小数据版]边权差值最小的生成树
这道题和最小生成树kruskal的代码几乎相同,只不过不一定是最小生成树,所以不一定从最短的边开始做生成树:所以将每一条边分别作为起点,然后枚举就行了...... #include <bits/ ...
- Beta版本冲刺第一天!
该作业所属课程:https://edu.cnblogs.com/campus/xnsy/SoftwareEngineeringClass2 作业地址:https://edu.cnblogs.com/c ...
- iOS 监测电话呼入
1.首先引入CoreTelephony框架,代码里: @import CoreTelephony; 项目设置里: 2.定义属性,建立强引用: @property (nonatomic, strong) ...