dp超时的另外一种优化,找规律(四塔问题)

针对四塔问题,本文介绍了一种动态规划的解决方案,并通过寻找规律进行优化,避免了高精度计算带来的超时问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

四塔问题

“汉诺塔”,是一个众所周知的古老游戏。现在我们把问题稍微改变一下:如果一共有4根柱子,
而不是3根,那么至少需要移动盘子多少次,才能把所有的盘子从第1根柱子移动到第4根柱子上呢?

为了编程方便,您只需要输出这个结果mod 10000的值。

输入
一个正整数n。(0<n<=50000)

输出
一个正整数,表示把n个盘子从第1根柱子移动到第4根柱子需要的最少移动次数mod 10000的值。

样例输入
15
样例输出
129

这道题一看到题,就是dp

那么

按照三塔问题的思路设dp(i)表示把i个盘子从一个柱子通过其他两个柱子移动到第四根柱子,在移动的时候我们发现,这还要用到3塔问题,那么我们应该预处理一下三塔问题

这以我们用f(i)表示把前i个盘子从一根柱子通过其他一根柱子移动到第三根柱子。

dp(i)=2(dp(i-1-k)*f(k))+1(0<=k<i)

由于最后是求出余数的最大值,那么用这个方程的话,就不满足同余定理,只能有高精度来算。高精度的话这道题超时很严重。

这时候打出前100的数据,仔细看可以发现 两个数之间的差值为2 2 4 4 4 8 8 8 8 16 16 16 16 16……找出这个的话,问题很easy了。

#include<cstdio>
#include<algorithm>
using namespace std;
const int mod = 10000;
const int Max_N = 50002;
int dp[Max_N];
int main()
{
    int i , j = 0, k = 2, t = 2;
    dp[1] = 1;
    for(i = 2;i <= Max_N-2;i++){
        j++;
        dp[i] = (dp[i - 1] + t) % mod;
        if(j == k){
            j = 0;
            k++;
            t *= 2;
            t %= mod;
        }
    }
    int n;
    while(scanf("%d",&n)!=EOF) printf("%d",dp[n]);
    return 0;
}

我们发现当一个操作性很强的dp题目出现时,我们可以通过找规律优化

转载于:https://www.cnblogs.com/star-eternal/p/7568543.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值