遞歸

正如郭偉老師講的,遞歸怎麼講都不爲過。自覺得基本功紮實的我認爲本身對遞歸已經足夠了解,上了郭偉老師的課發現本身還只是只知其一;不知其二啊啊啊。因此仍是要謙虛,要及時認真的作筆記。ios

遞歸有一下幾個重要的做用:git

  1. 替代多重循環(特別是在重數不肯定的時候)
  2. 解決原本就是用遞歸形式定義的問題
  3. 將問題分解爲規模更小的子問題進行求解

1替代多重循環(特別是在重數不肯定的時候)app

典型問題:求階乘,N皇后ide

2解決原本就是用遞歸形式定義的問題spa

典型問題:表達式求值,漢諾塔code

2.1表達式求值blog

遞歸定義的形式:遞歸

表達式 :項,項和項的加減運算ci

項:因子,因子和因子的乘除運算get

因子:'(’ 表達式 ')',整數

#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#include<map>
#define DEBUG(x) cout << #x << " = " << x << endl
using namespace std;
int exp_value();
int term_value();
int fact_value();
int exp_value()
{
    int result=term_value();
    bool more=true;
    while(more){
        char c=cin.peek();
        if(c=='+'||c=='-'){
            cin.get();
            int t=term_value();
            if(c=='+')result+=t;
            else result-=t;
        }
        else more=false;
    }
    return result;
}
int term_value()
{
    int result=fact_value();
    bool more=true;
    while(more){
        char c=cin.peek();
        if(c=='/'||c=='*'){
            cin.get();
            int t=fact_value();
            if(c=='/')result/=t;
            else result*=t;
        }
        else more=false;
    }
    return result;
}
int fact_value()
{
    int result=0;
    char c=cin.peek();
    if(c=='('){//c='c'
        cin.get();
        result=exp_value();
        cin.get();
    }
    else {
        while(isdigit(c)){
            result=result*10+c-'0';
            cin.get();
            c=cin.peek();
        }
    }
    return result;
}
int main()
{
    freopen("in.txt","r",stdin);
    printf("%d\n",exp_value());
    return 0;
}
View Code

2.2漢諾塔

#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#include<map>
#define DEBUG(x) cout << #x << " = " << x << endl
using namespace std;
///漢諾塔問題
///解決原本就是用遞歸形式定義的問題
void hanoi(int n,char src,char mid,char dst)
{
    if(n==1){
         cout<<src<<"->"<<dst<<endl;
        return;
    }
    hanoi(n-1,src,dst,mid);
    cout<<src<<"->"<<dst<<endl;
    hanoi(n-1,mid,src,dst);

}
int main()
{
//    freopen("in.txt","r",stdin);
    hanoi(8,'A','B','C');
    return 0;
}
View Code

3將問題分解爲規模更小的子問題進行求

典型問題:上臺階,放蘋果,算24

3.1上臺階

仍是有點不太明白,爲何f(n)=f(n-1)+f(n-2)?

#include<iostream>
#include<cstdio>
using namespace std;
int N;
int stairs(int n)
{
    if(n<0)return 0;
    if(n==0)return 1;
    return stairs(n-1)+stairs(n-2);
}
int main()
{
    freopen("in.txt","r",stdin);
    while(cin>>N){
        cout<<stairs(N)<<endl;
    }
}
View Code

3.2放蘋果

實話說,我根本想不出來。。。

#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#include<map>
#define DEBUG(x) cout << #x << " = " << x << endl
using namespace std;
int apple(int m,int n)
{
    if(n>m)return apple(m,m);
    if(m==0)return 1;
    if(n==0)return 0;
    return apple(m,n-1)+apple(m-n,n);
}
int main()
{
    int t,m,n;
    freopen("in.txt","r",stdin);
    cin>>t;
    while(t--){
        cin>>m>>n;
        cout<<apple(m,n);
    }
    return 0;
}
View Code

3.3算24

比較經典,4個數算二十四,能夠先算兩個數,以後就是三個數算24,將問題分解爲規模更小的子問題進行求解,大概就是這個意思吧。

#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#include<map>
#define DEBUG(x) cout << #x << " = " << x << endl
#define EPS 1e-6
using namespace std;
double a[5];
bool isEqual(double a,double b) {
    return abs(a-b)<=EPS;
}
bool count24(double a[],int n) {
    int m=0;
    double b[5];
    if(n==1) {
//            DEBUG(a[0]);
        if(isEqual(a[0],24.0))
            return true;
        else
            return false;
    }
    for(int i=0; i<n-1; i++) {
        for(int j=i+1; j<n; j++) {
            for(int k=0; k<n; k++) {
                if(k!=i&&k!=j) {
                    b[m++]=a[k];
                }
            }
            double r;
            r=a[i]+a[j];
            b[m]=r;
            if(count24(b,m+1))
                return true;

            r=a[i]-a[j];
            b[m]=r;
            if(count24(b,m+1))
                return true;

            r=a[j]-a[i];
            b[m]=r;
            if(count24(b,m+1))
                return true;
            if(!isEqual(a[i],0)) {
                r=a[j]/a[i];
                b[m]=r;
                if(count24(b,m+1))
                    return true;
            }
            if(!isEqual(a[j],0)) {
                r=a[i]/a[j];
                b[m]=r;
                if(count24(b,m+1))
                    return true;
            }
        }
    }
    return false;
}
int main() {
    freopen("in.txt","r",stdin);
    for(int i=0;i<4;i++){
        cin>>a[i];
    }
    printf("%d\n",count24(a,4));
    printf("%d\n",true);
    return 0;
}
View Code
相關文章
相關標籤/搜索