zoukankan      html  css  js  c++  java
  • #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))

    题解

    可以从连续数字本身的规律出发来进行统计,这样速度比较快,先不考虑多余的(0)的情况,假设从(0000-9999),这一万个连续的数字,(0)(9)用到的次数都是相同的,一万个四位数,(0)(9)这十个数字共用了(40000)次,每个数字使用了(4000)次。

    进一步推广,考虑所有(n)位数情况,从(n)(0)(n)(9),共(10n)(n)位数,(0)(9)十个数字平均使用,每个数字共用了(n*10^{n-1})

    有了这样的规律后,可以从高位向低位进行统计,最后再减去多余的(0)的个数。

    (n=3657)为例;(用(count)数组来存放(0)(9)各个数字的使用次数)

    最高位(千位)为3,从0千、1千到2千,000~999重复了3次,

    要做就做南波万
  • 相关阅读:
    一个思绪凌乱的前端
    如何将你的github仓库部署到github pages(github.io博客)
    聊一聊前端系列篇
    Centos7升级gcc极简教程
    Pycharm报错连接linux服务器报错:Could not verify `ssh-rsa` host key with fingerprint
    基于Pytorch的简单小案例
    windows安装Pytorch报错:from torch._C import * ImportError: DLL load failed: 找不到指定的模块”解决方案
    scrapy抓取豆瓣电影相关数据
    scrapy结合selenium抓取武汉市环保局空气质量日报
    scrapy抓取国家社科基金项目数据库
  • 原文地址:https://www.cnblogs.com/liuziwen0224/p/2019122600027TK.html
Copyright © 2011-2022 走看看