#2019122600027 递归五题
Posted liuziwen0224
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了#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("
");
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(iin [1,n],iin 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;
}
}
3 自然数拆分
任何一个大于(1)的自然数(n),总可以拆分成若干小于(n)的自然数之和,求出(n)的所有拆分.
题解
用数组(a)储存完成(n)的一种拆分,不完全归纳法的分析可知当(n=7)时,按照(a[1])分类,有(a[1]=1,a[1]=2,...,a[1]=dfrac{n}{2}),共(dfrac{n}{2})大类拆分。在每一类拆分时,(a[1]=i,a[2]=n-i),从(x=2),继续拆分从(a[x])开始,(a[x])能否拆分取决于(dfrac{a[x]}{2})是否大于等于(a[x-1])。递归过程的参数(t)指向要拆分的数(a[x])。
#include <cstdio>
#include <algorithm>
using namespace std;
void dfs(int t){
int i,j,k;
printf("%d=%d",n,a[1]);
for(i=2;i<=t;i++){
printf("+%d",a[i]);
}
printf("
");
j=t;k=a[j];
for(i=a[j-1];i<=k/2;i++){
a[j]=i;
a[j+1]=k-i;
}
}
int main(){
int i,j,k;
scanf("%d",&n);
for(i=1;i<=n/2;i++){
a[1]=i;
a[2]=n-i;
dfs(2);
}
4 页码统计
一本书的页码共(N)页,页码从(1)开始。请你求出全部页码中用了多少个(0,1,2,...,9),其中不含前导(0),即页码只能是(5),而不是(0005).((Nleq 10^9))
以上是关于#2019122600027 递归五题的主要内容,如果未能解决你的问题,请参考以下文章
JavaScript - 代码片段,Snippets,Gist
数据结构二叉树相关面试题 Java版 LeetCode题 ------- 二叉树