递归 递推 合集

递推递归一般先确立最后一天,最后一个数。

 

递归:调用函数找结果 从N到1再从1找到N;f(n)=f(n-1)+f(n-2)

If(n==1)

Return 1;

If(n==2)

Return 2;

Return f(n-1)+f(n-2);

 

递推:数据比较大的用递推 先初始化 f[1]=1  f[2]=2   for(i>=3;i<=n;i++) f(i)=f(i-1)+f(i-2)

 

打表:先把结果存在数组里

 

找素数 速度筛选

For(i=2;i<=n;i++)

For(j=2;j<i;j++)  //时间复杂度太高

 

Memset(prime,0,sizeof(prime));int型只能初始化成-1或0;

给char型初始化一个字节以内的数值量

初始化变量的地址,初始化的数,字节数

Sqrt开平方

Const Int max=1e6+7;1000000+7

Int prime[max];

//做标记

Void int(){

Memset(prime,0,sizeof(prime));

Int n=sqrt(max);

For(int i=2;i<=n;i++)

{

If(prime[i]==0 )

For(j=i*i;j<=max;j+=i)

Prime[j]=1;

}

//存数组

for(int i=2;i<=max;i++)

{

    if(prime[i]==0)

        prime[++prime[0]]=i;

    for(int j=1;j<=prime[0]&&prime[j]<=max/i;j++)

    {

        prime[prime[j]*i]=1;

        if(i%prime[j]==0)

            break

    }

}

 1.首先,所有参加晚会的人员都将一张写有自己名字的字条放入抽奖箱中; 然后,待所有字条加入完毕,每人从箱中取一个字条; 最后,如果取得的字条上写的就是自己的名字,那么“恭喜你,中奖了!” 大家可以想象一下当时的气氛之热烈,毕竟中奖者的奖品是大家梦寐以求的Twins签名照呀!不过,正如所有试图设计的喜剧往往以悲剧结尾,这次抽奖活动最后竟然没有一个人中奖! 我的神、上帝以及老天爷呀,怎么会这样呢? 不过,先不要激动,现在问题来了,你能计算一下发生这种情况的概率吗?

Input

输入数据的第一行是一个整数C,表示测试实例的个数,然后是C 行数据,每行包含一个整数n(1< n<=20),表示参加抽奖的人数。

Output

对于每个测试实例,请输出发生这种情况的百分比,每个实例的输出占一行, 结果保留两位小数(四舍五入)

这是一个错排问题,把第N个放在第K个位置有(i-1)种方法。如果第K个放在N的位置那么剩下的情况等于f[i-2] ,如果没有放在N上剩下的情况为f[i-1] 。由此得到递推公式。

#include <iostream>
#include<stdio.h>
using namespace std;

int main()
{
    int n,i,m,j;
    double sum=2;
    double result;
    double f[21]={0};
    f[1]=0,f[2]=1;
        cin>>n;
        for(j=0;j<n;j++)
        {
            sum=2;
            cin>>m;
                    for(i=3;i<=m;i++)
                    {
                         f[i]=(i-1)*(f[i-1]+f[i-2]);
                         sum*=i;
                    }
           result=(f[m]/sum)*100;
            printf("%.2f%%\n",result);

        }
    return 0;
}

2.假定一个字符串由m个H和n个D组成,从左到右扫描该串,如果字符H的累计数总是不小于字符D的累计数,那么,满足条件的字符串总数就恰好和下沙的沙粒一样多。” 
这就是当今著名的“宇春猜想”! 

Input

输入数据包含多个测试实例,每个占一行,由两个整数m和n组成,m和 n 分别表示字符串中H和D的个数。由于我们目前所使用的微机和老美的超级计算机没法比,所以题目给定的数据范围是(1<=n<=m<=20)。 

Output

对于每个测试实例,请输出下沙的沙粒到底有多少,计算规则请参考“宇春猜想”,每个实例的输出占一行。 

考虑最后一个字母是H还是D (1)是H 那么前面还剩m-1 H, n D (2) 是D 那么前面还有m H ,n-1 D。由此可得递推公式。

#include <iostream>

using namespace std;

int main()
{
   int n,i,j,m;
   long long f[21][21];
   f[1][1]=1;
   f[2][1]=2;
   f[2][2]=2;
   for(i=1;i<=20;i++)
    {f[i][1]=i;
    }
   for(i=2;i<=21;i++)
    for(j=i;j<21;j++)
    f[i-1][j]=0;
   while(cin>>m>>n)
   {
       for(i=2;i<=m;i++)
       {
            for(j=2;j<=i;j++)
        f[i][j]=f[i-1][j]+f[i][j-1];
       }
       cout<<f[m][n]<<endl;
   }
    return 0;
}

3.

在2×n的一个长方形方格中,用一个1× 2的骨牌铺满方格,输入n ,输出铺放方案的总数. 例如n=3时,为2× 3方格,骨牌的铺放方案有三种,如下图: 

Input

输入数据由多行组成,每行包含一个整数n,表示该测试实例的长方形方格的规格是2×n (0< n<=50)。

Output

对于每个测试实例,请输出铺放方案的总数,每个实例的输出占一行。

Sample Input

1
3
2

Sample Output

1
3
2

最后一块如果竖着放,把骨牌竖着放刚刚好,如果最后一块横着放那么就要把倒数第二块也横着放。由此得到递推公式

#include <iostream>
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<string.h>
using namespace std;
int main()
{
    long long f[51]={0,1,2};
    int n,m;
    while(cin>>n)
    {
        for(m=3;m<=n;m++)
            f[m]=f[m-1]+f[m-2];
        cout<<f[n]<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sinat_39654987/article/details/81110606