递归及递推问题 专题知识
来源:互联网 发布:好123导航网址源码 编辑:程序博客网 时间:2024/05/07 18:04
归专题
递归专题:
我个人认为递归是算法中很重要的武器,虽然递归的效率很慢,但他是我们学习其他算法的基础,而递归这一算法又很抽象,也很难调试,所以我认为我有必要要这里好好理解递归这一有力的武器。。
表达式的转化:
#include<cstdio>
#include<iostream>
#include<math.h>
#include <string>
using namespace std;
double calc()
{
char s[10];
cin>>s;
switch (s[0])
{
case '+': {calc();printf("+");calc();break;}
case '-': {calc();printf("-");calc();break;}
case '*': {calc();printf("*");calc();break;}
case '/': {calc();printf("/");calc();break;}
default:cout<<s;
}
}
int main()
{
double f = calc();
// printf("%f\n",f);
return 0;
}
逆波兰表达式:
阅读这个代码应该好理解点:
#include<stdio.h>
int n,m;
char s[21][21];
int visit[21][21];
int count;
void dfs(int x,int y)
{
visit[x][y]=1;
if(x-1>0&&!visit[x-1][y]&&s[x-1][y]=='.')
{
count++;
dfs(x-1,y);
}
if(y-1>0&&!visit[x][y-1]&&s[x][y-1]=='.')
{
count++;
dfs(x,y-1);
}
if(x+1<=n&&!visit[x+1][y]&&s[x+1][y]=='.')
{
count++;
dfs(x+1,y);
}
if(y+1<=m&&!visit[x][y+1]&&s[x][y+1]=='.')
{
count++;
dfs(x,y+1);
}
}
int main (void)
{
int i,j;
int x,y;
while(scanf("%d %d",&m,&n),n!=0||m!=0)
{
count=1;
for(i=1;i<21;i++)
for(j=1;j<21;j++)
visit[i][j]=0;
for(i=1;i<=n;i++)
{
getchar();
for(j=1;j<=m;j++)
{
scanf("%c",&s[i][j]);
if(s[i][j]=='@')
{
我个人认为递归是算法中很重要的武器,虽然递归的效率很慢,但他是我们学习其他算法的基础,而递归这一算法又很抽象,也很难调试,所以我认为我有必要要这里好好理解递归这一有力的武器。。
表达式的转化:
#include<cstdio>
#include<iostream>
#include<math.h>
#include <string>
using namespace std;
double calc()
{
}
int main()
{
}
逆波兰表达式:
//#include<isotream> #include<cstdio> #include<math.h> using namespace std; double exp() { char a[10]; scanf("%s",a); switch(a[0]){ case'+':return exp()+exp(); case'-':return exp()-exp(); case'*':return exp()*exp(); case'/':return exp()/exp(); default:return atof(a); } } int main() { double ans; ans=exp(); printf("%f",ans); return 0; }
放苹果
Time Limit: 1000MS Memory Limit: 10000KTotal Submissions: 17936 Accepted: 11317
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 3Sample Output
8Source
lwx@POJ
很好的算法:
f(m, n) = f(m-n, n) + f(m, n-1)
f(m, n): 把m个苹果放到n个盘子中的方法数
f(m, n-1): 把m个苹果放到n-1个盘子中的方法数(其中至少有一个空盘子)
f(m-n, n): 把m个苹果放到n个盘子中,而且每个盘子中都有苹果(先拿n个出来,等m-n个放好了,然后每个盘子放一个)
#include <iostream>
#include <vector>
#include <string>
#include <math.h>
#include <iomanip>
#include <stdlib.h>
using namespace std;
int PlaceApple( int m, int n)
{
if(m < 0)
return 0;
if(m == 0) //每个盘子一个
return 1;
if(n == 1) //只有一个盘子
return 1;
return PlaceApple(m - n, n) + PlaceApple(m, n - 1);
}
intmain()
{
int num,m,n;
cin >>num;
while (num >0)
{
cin >>m>>n;
cout <<PlaceApple(m,n)<<endl;
num --;
}
}
例子2:很好的算法:
f(m, n) = f(m-n, n) + f(m, n-1)
f(m, n): 把m个苹果放到n个盘子中的方法数
f(m, n-1): 把m个苹果放到n-1个盘子中的方法数(其中至少有一个空盘子)
f(m-n, n): 把m个苹果放到n个盘子中,而且每个盘子中都有苹果(先拿n个出来,等m-n个放好了,然后每个盘子放一个)
#include
#include
#include
#include
#include
#include
using
}
int
}
Red and Black
Time Limit: 1000MS Memory Limit: 30000KTotal Submissions: 14298 Accepted: 7416
Description
There is a rectangular room, covered with square tiles. Each tile is colored either red or black. A man is standing on a black tile. From a tile, he can move to one of four adjacent tiles. But he can't move on red tiles, he can move only on black tiles.
Write a program to count the number of black tiles which he can reach by repeating the moves described above.
Write a program to count the number of black tiles which he can reach by repeating the moves described above.
Input
The input consists of multiple data sets. A data set starts with a line containing two positive integers W and H; W and H are the numbers of tiles in the x- and y- directions, respectively. W and H are not more than 20.
There are H more lines in the data set, each of which includes W characters. Each character represents the color of a tile as follows.
'.' - a black tile
'#' - a red tile
'@' - a man on a black tile(appears exactly once in a data set)
The end of the input is indicated by a line consisting of two zeros.
There are H more lines in the data set, each of which includes W characters. Each character represents the color of a tile as follows.
'.' - a black tile
'#' - a red tile
'@' - a man on a black tile(appears exactly once in a data set)
The end of the input is indicated by a line consisting of two zeros.
Output
For each data set, your program should output a line which contains the number of tiles he can reach from the initial tile (including itself).
Sample Input
6 9 ....#. .....# ...... ...... ...... ...... ...... #@...# .#..#. 11 9 .#......... .#.#######. .#.#.....#. .#.#.###.#. .#.#..@#.#. .#.#####.#. .#.......#. .#########. ........... 11 6 ..#..#..#.. ..#..#..#.. ..#..#..### ..#..#..#@. ..#..#..#.. ..#..#..#.. 7 7 ..#.#.. ..#.#.. ###.### ...@... ###.### ..#.#.. ..#.#.. 0 0
Sample Output
45 59 6 13
Source
Japan 2004 Domestic
解法1:
上面的return 1+f(x-1,y)+f(x+1,y)+f(x,y+1)+f(x,y-1)这里属于递推公式,这时比如要计算f(x,y)的时,这时就会向这f(x-1,y)这个方向一直深搜下去,一直到f(x-1,y)这个方向没有地方可以走了,这时就要在当前的位置继续深搜f(x-1,y)这个方向,接着就会继续深搜f(x-1,y)这个方向,同样直到f(x-1,y)这个方向不能再进行时,继续深搜f(x+1,y)这个方向,直到这个方向无路可走,就继续深搜f(x,y+1)这个方向.......一直递归下去。到了最后一个方向不行时,这时就要返回上一层继续搜这个方向还未搜到的点.....一直的返回,解法1:
阅读这个代码应该好理解点:
#include<stdio.h>
int n,m;
char s[21][21];
int visit[21][21];
int count;
void dfs(int x,int y)
{
}
int main (void)
{