题目描述

现在有四个栈,其中前三个为空,第四个栈从栈顶到栈底分别为1,2,3,…,n。每一个栈只支持一种操作:弹出并压入。它指的是把其中一个栈A的栈顶元素x弹出,并马上压入任意一个栈B中。但是这样的操作必须符合一定的规则才能进行。规则1:A栈不能为空。规则2:B栈为空或x比B栈栈顶要小。

对于给定的n,请你求出把第四个栈的n个元素全部移到第一个栈的最少操作次数。

由于最少操作次数可能很多,请你把答案对1000007取模。

输入输出格式

输入格式:

一行,一个n

输出格式:

一行,一个正整数,为把最少操作次数 mod 1000007的值

输入输出样例

输入样例#1:

2

输出样例#1:

3

说明

对于30%的数据,n<=8

对于60%的数据,n<=60

对于100%的数据,n<=2*10^9

此题实质上是Hanoi四塔问题。

那么Hanoi四塔问题是不是可以通过三塔问题的结论来解决呢?答案是:可以,首先要知道,三塔问题是借助1个中间柱完成转移,四塔问题是借助2个中间柱完成转移,以上两句话看似是废话,其实很重要!

四塔问题可以转化为:对于N个盘子的四塔问题,先将j(0<=j<=N)个盘子通过两个中间柱(一个中间柱,一个目标柱)移动到另一个目标柱,然后将N-j个盘子通过一个中间柱移动到目标柱,最后将j个盘子通过两个中间柱(一个起始柱,一个中间柱)转移到目标柱

递推方程:H[i]表示三塔问题的结论,即i个盘子通过一个中间柱转移需要多少步。F[i]表示四塔问题的结果,即i个盘子通过两个中转柱移动到4号柱需要多少步。

则,F[i] = min{2*F[j]+H[i-j]}(1<=i<=n;0<=j<=i)

以上方程的复杂度为O(N^2),是比较低效的方法。那么,有没有更为优化的方法呢?

答案是有的,我们可以做到O(N),但是没有用。上述算法而言,我们都是要通过比较大小找出最小值的,且不论H[i]超不超int的问题,我们这题,每次%1000007后,我们根本无法保证找到的最小的就是最小的,因为有可能1000008%1000007<1000006%1000007,因为取模运算的存在。

怎么办?找一个新的规律,f[i],表示i个盘子的四塔问题的解。我们通过求出f[i]的值,发现了一个新的规律:

f[1] : 0 +2^0=1;

f[2] : 1 +2^1=3;

f[3] : 3 +2^1=5;

f[4] : 5 +2^2=9;

f[5] : 9 +2^2=13;

f[6] : 13+2^2=17;

f[7] : 17+2^3=25;

f[8] : 25+2^3=33;

f[9] : 33+2^3=41;

f10] : 41+2^3=49;

f[11]: 49+2^4=65;

即,f[i]-f[i-1]的值是有规律的,1个2^0,2个2^1,3个2^2,4个2^3,5个2^4以此类推。所以很容易写出代码,于是这题就这么迎刃而解了。

#include<cstdio>
using namespace std;
long long n,k,v,ans,mo=1e6+7;
int main()
{
scanf("%lld",&n);
k=1;
v=1;
for(k=1,v=1;n>k;)
{
n-=k;
k++;
v=(v+v)%mo;
ans=(ans+k*v)%mo;
}
printf("%lld",(ans+n*v)%mo);
return 0;
}

洛谷 P1573 栈的操作的更多相关文章

  1. 洛谷P1573 栈的操作 [2017年6月计划 数论11]

    P1573 栈的操作 题目描述 现在有四个栈,其中前三个为空,第四个栈从栈顶到栈底分别为1,2,3,…,n.每一个栈只支持一种操作:弹出并 压入.它指的是把其中一个栈A的栈顶元素x弹出,并马上压入任意 ...

  2. 洛谷 p1044 栈 【Catalan(卡特兰数)】【经典题】

    题目链接:https://www.luogu.org/problemnew/show/P1044 转载于:https://www.luogu.org/blog/QiXingZhi/solution-p ...

  3. 洛谷 P1044 栈

    题目背景 栈是计算机中经典的数据结构,简单的说,栈就是限制在一端进行插入删除操作的线性表. 栈有两种最重要的操作,即pop(从栈顶弹出一个元素)和push(将一个元素进栈). 栈的重要性不言自明,任何 ...

  4. 洛谷P1044 栈(Catalan数)

    P1044 栈 题目背景 栈是计算机中经典的数据结构,简单的说,栈就是限制在一端进行插入删除操作的线性表. 栈有两种最重要的操作,即pop(从栈顶弹出一个元素)和push(将一个元素进栈). 栈的重要 ...

  5. 洛谷——P1044 栈

    P1044 栈——卡特兰数 题目背景 栈是计算机中经典的数据结构,简单的说,栈就是限制在一端进行插入删除操作的线性表. 栈有两种最重要的操作,即pop(从栈顶弹出一个元素)和push(将一个元素进栈) ...

  6. 洛谷P1044栈(DP)

    题目背景 栈是计算机中经典的数据结构,简单的说,栈就是限制在一端进行插入删除操作的线性表. 栈有两种最重要的操作,即poppoppop(从栈顶弹出一个元素)和pushpushpush(将一个元素进栈) ...

  7. 洛谷P3178 [HAOI2015]树上操作

    题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种:操作 1 :把某个节点 x 的点权增加 a .操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 ...

  8. 洛谷P1044 栈

    之前看这题还是一头雾水,现在看:啊啊啊lydnb! 思考了一段时间,发现可以用DP. 令f[i]表示有i辆车时的方案数. 我一开始考虑的是在后面加车,可是这样搞不出状态转移方程来. 然后我考虑从前面加 ...

  9. 洛谷P3178 [HAOI2015]树上操作(dfs序+线段树)

    P3178 [HAOI2015]树上操作 题目链接:https://www.luogu.org/problemnew/show/P3178 题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边 ...

随机推荐

  1. IDE简介

    IDE(Integrated Development Environment) 集成开发环境 十种集成开发工具: 微软 Visual Studio (VS) NetNeans PyCharm Inte ...

  2. LeetCode(43)Multiply Strings

    题目 Given two numbers represented as strings, return multiplication of the numbers as a string. Note: ...

  3. String字符串类的获取功能

    StringDemo.java /* * String类的获取功能: * int length():获取字符串的长度,其实也就是字符个数 * char charAt(int index):获取指定索引 ...

  4. 易接SDK ios9以上无法弹出充值界面的一种情况

    充值需要用到http请求: 打开info.plist, 在app tansport security  setting 这个项 ,  加入  NSAllowsArbitraryLoads YES

  5. noip模拟赛 区间

    分析:要遍历所有的区间,肯定是枚举左端点,然后再枚举右端点.关键是怎么高效地求区间&,|,一般而言是用前缀和的,但是&,|不满足区间可减性,所以可以考虑线段树?这道题不带修改操作,用线 ...

  6. HDU 5950 Recursive sequence 递推转矩阵

    Recursive sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Other ...

  7. Mybatis教程(一)

    1      Mybatis教程(一) 学习过的持久层框架:DBUtils , Hibernate Mybatis就是类似于hibernate的orm持久层框架. 为什么学Mybatis? 目前最主流 ...

  8. M2Crypto

    M2Crypto = Python + OpenSSL + SWIG M2Crypto is a crypto and SSL toolkit for Python. 上面是M2Crypto的READ ...

  9. 记一次调试python内存泄露的问题

    转载:http://www.jianshu.com/p/2d06a1a01cc3 这两天由于公司需要, 自己编写了一个用于接收dicom文件(医学图像文件)的server. 经过各种coding-de ...

  10. python:functools之partial

    示例:from operator import addimport functoolsprint add(1,2) #3add1 = functools.partial(add,1)print add ...