zoukankan      html  css  js  c++  java
  • 递推求解

    递推求解

    步骤

    • 得到简单情况的解,譬如 n=1, n=2 等;
    • 假设规模为 n-1 的情况已经解决;
    • 当规模扩大到 n 时,如何枚举出所有的情况,并且要确保对于每一种子情况都能用已经得到的数据解决;

    例题:

    1. 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0):
    class Solution {
    public:
        int Fibonacci(int n) {
            if(n==0)
                return 0;
            if(n==1)
                return 1;
            if(n==2)
                return 1;
            return Fibonacci(n-1)+Fibonacci(n-2);
        }
    };
    
    1. 一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)
    class Solution {
    public:
        int jumpFloor(int n) {
            if(n==0)
                return 1;
            if(n==1)
                return 1;
            if(n==2)
                return 2;
            return jumpFloor(n-1)+jumpFloor(n-2);
        }
    };
    
    1. 一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法:
    class Solution {
    public:
        int jumpFloorII(int number) {
            if (number==0)
                return 1;
            int sum = 0;
            while(number>0){
                number -= 1;
                sum += jumpFloorII(number);
            }
            return sum;
        }
    };
    
    1. (牛客网)我们可以用21的小矩形横着或者竖着去覆盖更大的矩形。请问用n个21的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
    class Solution {
    public:
        int rectCover(int number) {
            if (number==0)
                return 0;
            if (number==1)
                return 1;
            if (number==2)
                return 2;
            return rectCover(number-1)+rectCover(number-2);
        }
    };
    

    注: 上述解法在(HDU2046)显示超时,使用下面可通过。

    #include<iostream>
    int main()
    {
        using namespace std;
        __int64 a[51]={0,1,2},n;
        for(int i=3;i<=50;i++)
            a[i]=a[i-1]+a[i-2];
        while(cin>>n)
        {
            cout<<a[n]<<endl;
        }
    }
    
    1. (HDU 2050)我们看到过很多直线分割平面的题目,今天的这个题目稍微有些变化,我们要求的是n条折线分割平面的最大数目。比如,一条折线可以将平面分成两部分,两条折线最多可以将平面分成7部分,具体如下所示。
    #include <iostream>
    using namespace std;
    int total(int n);
    int main(){
    	int n,k;
    	cin >> n;
    	while(n--){
    		cin >> k;
    		cout << total(k) << endl;
    	}
    	return 0;
    }
    
    int total(int n){
    	if (n==1)
    		return 2;
    	return total(n-1) + 4*(n-1) + 1;
    }
    
    1. (HDU2044) 有一只经过训练的蜜蜂只能爬向右侧相邻的蜂房,不能反向爬行。请编程计算蜜蜂从蜂房a爬到蜂房b的可能路线数。
    #include <iostream>
    using namespace std;
    
    int number1(int n){
        if(n==0)
            return 1;
        if(n== 1)
            return 1;
        if (n==2)
            return 2;
        return number1(n-1) + number1(n-2);
    }
    
    int main(){
        int n,t1,t2;
        cin >> n;
        while(n--){
            cin >> t1 >> t2;
            cout << number1(t2-t1) << endl;
        }
    }
    

    注释: 问题依旧是TLE,可先把数组存下来,然后直接读取;

    #include <stdio.h>
    int main()
    {
        int i, j, n;
        __int64 d[51] = {1, 1, 2,};
        for (i = 3; i < 51; i++)
            d[i] = d[i-1] + d[i-2];
        scanf("%d", &n);
        while (n-- && scanf("%d%d", &i, &j) != EOF)
            printf("%I64d
    ", i > j ? 0 : d[j-i]);
        return 0;
    }
    
    1. (HDU 2045) 有排成一行的n个方格,用红(Red)、粉(Pink)、绿(Green)三色涂每个格子,每格涂一色,要求任何相邻的方格不能同色,且首尾两格也不同色.求全部的满足要求的涂法.
    #include <iostream>
    using namespace std;
    
    int main(){
        int n,i;
        long long pre[55]={-1,3,6,6};
        for(i=4;i<55;i++)
            pre[i] = pre[i-1] + 2*pre[i-2];
        while(cin >>n)
            cout << pre[n] << endl;
    }
    
    1. (HDU 2049)假设一共有N对新婚夫妇,其中有M个新郎找错了新娘,求发生这种情况一共有多少种可能.

    思路:先找出m个选错新娘的新郎,m个新郎错排。

    
    #include <iostream>
    using namespace std;
    
    int main(){
        int i,c,n,m;
        cin >> c;
        long long n_l[21] = {1,1,2};
        long long m_l[21] = {0,0,1,2};
        for (i=3;i<21;i++){
            n_l[i] = n_l[i-1]*i;
        }
        for (i=4;i<21;i++){
            m_l[i] = (i-1)*m_l[i-1] + (i-1)*m_l[i-2];
        }
        while(c--){
            cin >> n >> m;
            cout << n_l[n]/n_l[m]/n_l[n-m] *m_l[m] << endl;
        }
    }
    
    1. (HDU 2047) 准备在上面刻下一个长度为n的只由"E" "O" "F"三种字符组成的字符串(可以只有其中一种或两种字符,但绝对不能有其他字符),阿牛同时禁止在串中出现O相邻的情况,
    #include <iostream>
    
    using namespace std;
    
    int main(){
        int n,i;
        long long list[41]={0,3,8};
        for (i=3;i<41;i++)
            list[i] = 2*list[i-1] + 2*list[i-2];
        while(cin >>n){
            cout << list[n] << endl;
        }
            
    }
    
    1. (HDU 2048)首先,所有参加晚会的人员都将一张写有自己名字的字条放入抽奖箱中;然后,待所有字条加入完毕,每人从箱中取一个字条;最后,如果取得的字条上写的就是自己的名字,那么“恭喜你,中奖了!”,求没有人获奖的概率。

    思路: 错排公式。(f(n)=(n-1)(f(n-1)+f(n-2))
    如果最后一个人和((n-1))中的一个交换后,正好满足错排,则为((n-1)*f(n-1))
    如果最后一个人和((n-1))个人中的一个交换后,不满足情况,说明这两个人正好拿着对方的名字,所以((n-1)*f(n-2))

    #include <iostream>
    using namespace std;
    int main(){
        int c,n,i;
        long long list[21]={0,0,1,2};
        long long list_d[21]={1,1,2,6};
        for(i=4;i<21;i++){
            list_d[i] = list_d[i-1]*i;
            list[i] = (i-1)*(list[i-1]+list[i-2]);
        }
        cin >> c;
        while(c--){
            cin >> i;
            printf("%.2f%%
    ",100*(float)list[i]/list_d[i]);
        }
    }
    
  • 相关阅读:
    case when in sql server's stored procedure
    Hadoop-2.2.0中国文献—— MapReduce 下一代 -- 公平调度
    cocos2d-x游戏循环和日程安排
    归并+高速分拣
    【Nginx】启动过程
    IOS线程操作(3)
    Android最方便的数据库--LitePal
    Android采用Application总结一下
    POJ 2151 Check the difficulty of problems (动态规划-可能DP)
    乞讨N!到底有多少0
  • 原文地址:https://www.cnblogs.com/curtisxiao/p/10561145.html
Copyright © 2011-2022 走看看