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


    四塔问题

    “汉诺塔”,是一个众所周知的古老游戏。现在我们把问题稍微改变一下:如果一共有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题目出现时,我们可以通过找规律优化

  • 相关阅读:
    java 28
    java 28
    java 27
    java 27
    java 27
    java 27
    java 27
    java 27
    java 27
    java 27
  • 原文地址:https://www.cnblogs.com/star-eternal/p/7568543.html
Copyright © 2020-2023  润新知