#2019122600027 递归五题

目录

1 全排列

2 01背包

3 自然数拆分

4 页码统计

5 汉诺塔

1 全排列

生成从\(1\)\(n\)的全排列

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
int a[25];
bool vis[25];
int n;
int ans=0; 
void f(int x){
    if(x==n+1){
        ans++;
            for(int i=1;i<=n;i++){
                printf("%5d",a[i]);
            }
            printf("\n");
        return;
    }
    for(int i=1;i<=n;i++)
    {
        if(vis[i]==1) continue;
        bool q=1;
        if(q){
            vis[i]=1;
            a[x]=i;
            f(x+1);
            vis[i]=0;
        }
        
    }
    return ;
}
int main( ){
    scanf("%d",&n);
    f(1);
    printf("%d",ans); //...
    return 0;
} 

2 01背包问题

设一背包可容纳物品最大质量为\(M\),现有\(n\)件物品,质量是\(m_i(i\in [1,n],i\in N)\),要从这些物品中挑选若干件,使得质量之和恰好是\(K\),询问能否做到.

题解

\(knap(M,n)\)表示寻找的问题。
(1)先取最后一个物品\(m_n\)放入背包,如果\(m_n=M\),则return true.
(2)若\(m_n<M\),则\(M-m_n<0\),如果还有可选物品。即为\(n>1\),考虑\(knap(M-m_n,n-1)\)是否有解,如果有就return true.否则\(knap(M,n)\)转化为\(knap(M,n-1)\),即放弃最后一个物品,在前\((n-1)\)个物品内考虑问题.
(3)若\(m_n>M\),则第\(n\)件物品不能装入包中,这时如果还有可选物品,即\(n>1\),那么\(knap(M,n)\)转化为\(knap(m,n-1)\)

bool knap(int m,int n){
    if(m[n]==m) return true;
    else if(m[n]<m){
        if(n>1){
            if(knap(m-m[n],n-1)) return true;
            else return knap(m,n-1);
        }
        else return false;
    }
    else{
        if(n>1) return knap(m,n-1);
        else return false; 
    }
} 

猜你喜欢

转载自www.cnblogs.com/liuziwen0224/p/2019122600027TK.html