记忆化搜索算法的一个简单应用

探讨了Collatz问题,并使用记忆化搜索算法优化求解百万内产生最长Collatz序列的起始数字,通过对比普通方法与记忆化搜索方法的时间复杂度,展示了优化算法的重要性。

题目

The following iterative sequence is defined for the set of positive integers:

n → n/2 (n is even)
n → 3n + 1 (n is odd)

Using the rule above and starting with 13, we generate the following sequence:

13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1
It can be seen that this sequence (starting at 13 and finishing at 1) contains 10 terms. Although it has not been proved yet (Collatz Problem), it is thought that all starting numbers finish at 1.

Which starting number, under one million, produces the longest chain?

NOTE: Once the chain starts the terms are allowed to go above one million.

分析思路

  • 由于一个确定的整数在题目的规则下一定也会经历唯一确定步数,所以没有必要每个整数都从头到尾重新计算一遍
  • 将中间的计算结果保存下来,减少后续的重新计算,这种技巧常常被用在搜索算法中,常被叫做“记忆化搜索”

代码如下

两种不同方法的对比

普通方法(暴力求解),时间复杂度高

#include<stdio.h>
#define max_n 1000000

long long get_len(long long x) {
    if (x == 1) return 1;
    if (x & 1) return get_len(3 * x + 1) + 1;
    return get_len(x >> 1) + 1;
}

int main() { 
    int ans = 0, num = 0;
    for (int i = 2; i < max_n; ++i) {
        int l = get_len(i);
        if (l > ans) ans = l , num = i;
    }
    printf("%d\n", num);

    return 0;
}

记忆化搜索方法,时间复杂度低

#include<stdio.h>
#define max_n 1000000
#define keep_max_length 1000000

int keep[keep_max_length] = {0};

long long get_len(long long x) {
    if (x == 1) return 1;
    if (x < keep_max_length && keep[x]) return keep[x];
    int ret;
    if (x & 1) ret = get_len(3 * x + 1) + 1;
    else ret = get_len(x >> 1) + 1;
    if (x < keep_max_length) keep[x] = ret;
    return ret;
}

int main() {
    int ans = 0, num = 0;
    for (int i = 2; i < max_n; ++i) {
        int l = get_len(i);
        if (l > ans) ans = l , num = i;
    }
    printf("%d\n", num);

    return 0;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值