递推(三):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又代表的 ...
随机推荐
- bzoj1087互不侵犯King——状压DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1087 水题... 然而犯了两个致命小错误,调了好半天...详见注释. 代码如下: #incl ...
- redhat 关机注销命令详解
一.注销,关机,重启 注销系统的logout命令 1,Logout 注销是登陆的相对操作,登陆系统后,若要离开系统,用户只要直接下达logout命令即可: [root@localhost root]# ...
- 《SONG FROM PI: A MUSICALLY PLAUSIBLE NETWORK FOR POP MUSIC GENERATION》论文笔记
出处:ICLR 2017 Motivation 提出一个通用的基于RNN的pop music生成模型,在层次结构中封装了先验乐理知识(prior knowledge about how pop mus ...
- 一个C#文件传输模块,支持断点续传
一个C#文件传输模块,支持断点续传 最近做一个程序需要传送文件,在网上找了好久也没找到好用的方案,于是自己写了一个,与大家分享,希望大家帮忙改进,拍砖欢迎-文件采取分块发送,每块单独校验,能够保证文件 ...
- IOS 的调试模式
iOS调试模式分为: 断点单步调试: 全局断点调试: 僵尸调试: 暴力调试: 这里主要说一下什么是僵尸调试模式? .为什么会使用NSZombieEnabled? 应用调试可能会收到类似 Thread ...
- ORA-01152: 文件 1 没有从过旧的备份中还原
转自:http://blog.itpub.net/8520577/viewspace-1255794/ 做了一个全备 RMAN> show all; 使用目标数据库控制文件替代恢复目录db_un ...
- cocos2d-x 坐标系解惑
1.CCTouch* touch->getLocation() ---- 返回当前触摸点在openGL坐标系中的位置 openGL坐标系,原点在左下角,x向右为正,y向上为正. 2.CCTouc ...
- Android 布局之GridLayout(转载)
转载:http://www.cnblogs.com/skywang12345/p/3154150.html 1 GridLayout简介 GridLayout是Android4.0新提供的网格矩阵形式 ...
- POJ 1384【完全背包】
题意: 已知储蓄罐满时的质量f以及空时质量e, 有n种硬币,每种硬币的价值为p,质量为w, 求该储蓄罐中的最少有多少钱? 思路: 完全背包思想,问题是在一个重量下的最小价值 那么只要变一下符号就好了? ...
- python之迷宫BFS
# @File: maze_queue_bfs from collections import deque maze = [ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 0 ...