算法基本概念及思维导图-n鸡问题和页码问题

 一、学习内容

第一章学习了算法与程序、算法复杂性分析及NP完全性理论的相关内容。思维导图如下:

1. 算法

算法是有若干条指令组成的有穷序列,程序=算法+数据结构。

算法满足5条性质,分别是输入、输出、确定性、有限性和可行性,缺一不可。

程序是算法用某种程序设计语言的具体实现。

2. 算法复杂性

算法的复杂性是算法运行需要的计算机资源的量,需要时间资源的量称为时间复杂性,需要空间资源的量称为空间复杂性。这个量只依赖于要解的问题的规模、算法的输入和算法本身的函数。

时间复杂度:问题规模n的渐近阶函数表示法。

根据符号O的定义,用它评估算法的复杂性,得到的只是当规模充分大时的一个上界。这个上界的阶越低,则评估越精确,结果就越有价值。有如下运算规则:

①O(f)+O(g)=O(max(f, g))。

②O(f)+O(g)=O(f+g)。

③O(f)O(g)=O(fg)。

④如果g(N)=O(f(N),则O(f)+O(g)=O(f)。

⑤O(Cf(M)=O(f(M)),其中C是一个正的常数。

⑥f=O(f)。

根据符号π的定义,用它评估算法的复杂性,得到的只是该复杂性的一个下界。这个下界的阶越高,则评估越精确,结果就越有价值。

3. NP完全性理论

确定性算法:设A是求解问题B的一个算法,如果在算法的整个执行过程中,每一步只有一个确定选择,则称算法A是确定性算法。

P类问题(多项式问题):如果对于某个判定问题B,存在一个非负整数k,对于输入规模为n的实例,能够以的时间运行一个确定性算法,得到肯定或否定答案,则该判定问题B是一个P类问题。所有可以在多项式时间内求解的判定问题构成P类问题。

NP类问题(非确定性多项式问题):非确定性算法将问题求解分为猜测和验证两个阶段。

算法的猜测阶段是非确定性的,给出问题解的一个猜测。算法的验证阶段是确定性的,验证猜测阶段给出的解的正确性。

设算法A是解一个判定问题Q的非确定性算法。如果算法A的验证阶段可以在多项式时间内完成,则称算法A是一个多项式时间非确定性算法,也称问题Q是非确定性多项式时间可解的。

P类问题是确定性计算模型下的易解问题类,而NP类问题是非确定性计算模型下的易验证问题类。


二、算法设计与分析

1.N鸡问题

用N元钱买N只鸡,公鸡每只5元,母鸡每只3元,小鸡1元3只,N元钱必须刚好买N只鸡,鸡必须整只买,有几种买法呢?

1.1设计算法

  • 设公鸡有i只,母鸡j只,小鸡n-i-j只,买小鸡的钱数为n-i×5-j×3,
  • 以小鸡只数可推出等式:
  • (n-i×5-j×3)*3=n-i-j
  • 由公鸡母鸡的只数设置双循环遍历,
  • 一只公鸡5元钱,共n元钱,所以公鸡只数 i≤n/5,同理得,母鸡只数 j≤n/3。

1.2代码

n=int(input("请输入钱的总数:"))
a=[]
b=[]
c=[]
t=0
for i in range(int(n/5)):
    for j in range(int(n/3)):
        if (n-i*5-j*3)*3==n-i-j:
            a.append(i)
            b.append(j)
            c.append(n-i-j)
            t+=1
print('共有%d种买法'%t)
for i in range(t):
    print('买法%d:公鸡%d只,母鸡%d只,小鸡%d只'%(i+1,a[i],b[i],c[i]))

测试数据1:

测试数据2:

1.3时间复杂度分析

  • 由公鸡母鸡的只数设置了双循环遍历,
  • 使用了双重循环,所以该算法的时间复杂度为


2.页码问题

一本书的页码从自然数1开始顺序编码直到自然数n。书的页码按照通常的习惯编排,每个页码都不含多余的前导数字0。数字计数问题要求对给定书的总页码n(<=200000),计算出书的全部页码中分别用到多少次数字0,1,2,…,9。

2.1设计算法

  • 设当前页码为i,当前页码的个位数为j,
  • 使用while语句,判断完当前位数后进行j/10,由此完成判断当前页码每一位数的功能,
  • 由页码页数设置单循环遍历。

2.2代码

import pandas as pd
import time
n=int(input("请输入书的总页码:"))
start_time = time.time()
a=[0]*10
for i in range(1,int(n+1)):
    if n<0:
        break
    else:
        j=i
        while j!=0:   #每次只判断个位数
            a[int(j%10)]+=1
            j=int(j/10)
print('全部页码中用到的数字次数如下')
d=pd.DataFrame([a])
print(d)
tt= time.time() - start_time
print('耗时',tt*1000,'ms')

测试数据1:

测试数据2:

2.3时间复杂度分析

  • 由页码页数设置单循环遍历,
  • 由于内循环while次数与n(<=200000)的位数有关,最多进行六次,所以该算法的时间复杂度为

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值