目前做过的最纠结的一道递推题。

情况比较多,比较复杂。。。

这题最主要的还是要推出当m=2 时和m>2时,用什么方法最优。

给个数据

n=3,m=2   需要48

n=3,m=3 需要81

如果在纸上把这两种情况推出来,这题就容易找到递推。

m=1,就是最基础的汉诺塔递推了。

很O_O的汉诺塔

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 561    Accepted Submission(s): 67

Problem Description
O_O汉诺塔包含n种不同大小盘,每种大小m个; 要求每次仅移动一个盘,不允许一个较大的盘放在较小盘上。 并且要求最后排列所有相等大小盘按原来从上到下次序,并且只能按规定的方向搬运,如图(比如A直接搬运到C是不允许的!). 求已知n,m的情况下 从A搬运到C所有盘所用的最少次数。

 
Input
每行输入n和m两个整数 0<n<1000,0<m<100;
 
Output
每行输出对应解,为避免高精度将结果对20090308取模.
 
Sample Input
1 3
2 4
 
Sample Output
6
28
 
Source
 
//
// main.cpp
// hdu2587
//
// Created by 陈加寿 on 16/3/17.
// Copyright © 2016年 chenhuan001. All rights reserved.
// #include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define N 1100
#define MOD 20090308 long long dp[N][]; //来一个统计,每个小块被搬多少次
long long save[N][N][];
long long m;
int tn;
int g[N]; long long dfs(int n,int flag)
{
if(dp[n][flag]!=-) return dp[n][flag];
if(flag == )
{
dp[n][flag] = (*dfs(n-,)+*m+dfs(n-,))%MOD;
save[n][n][flag]=;
if(n== tn)
{
for(int i=;i<=n-;i++)
{
save[n][i][flag]+=save[n-][i][]+save[n-][i][];
save[n][i][flag]%=;
}
}
else
{
for(int i=;i<=n-;i++)
{
save[n][i][flag]+=*save[n-][i][]+save[n-][i][];
save[n][i][flag]%=;
}
}
}
else
{
dp[n][flag] = (*dfs(n-,)+m)%MOD;
save[n][n][flag] = ;
for(int i=;i<=n-;i++)
{
save[n][i][flag] += *save[n-][i][];
save[n][i][flag]%=;
}
}
return dp[n][flag];
} int main() {
int n;
while(cin>>n>>m)
{
tn = n;
//来测试一种方法。!
memset(save,,sizeof(save));
memset(g,,sizeof(g));
memset(dp,-,sizeof(dp));
dp[][] = m;
save[][][] = ;
dp[][] = *m;
save[][][] = ;
dfs(n,);
//对于n
if(m>)
{
if(n<=)
{
cout<<dp[n][]<<endl;
}
else
{
cout<<(dp[n][]+*(dp[n-][]+dp[n-][]))%MOD<<endl;//进行一次调整。
}
}
else if(m==)
{
//m == 2时
if(n<=)
{
cout<<dp[n][]<<endl;
}
else
{
//int cnt=1;
//cout<<(dp[n][1]+2*(dp[n-2][1]+dp[n-2][0])-3*m*(n-2) )%MOD<<endl;//进行一次调整。
//各种不对。
long long tans=;
for(int i=n;i>;i--)
{
//把第i个块,从A放入C中
//第一步判断是否需要调整
if(g[i] == )
{
tans = (tans + dp[i-][] + dp[i-][])%MOD;//调整
for(int j=;j<i;j++)
{
g[j] += save[i-][j][]+save[i-][j][];
g[j]%=;
}
}
tans = (tans + dp[i-][] + dp[i-][]+*m)%MOD;
for(int j=;j<i;j++)
{
g[j] += save[i-][j][]+save[i-][j][];
g[j]%=;
}
}
cout<<(tans+)%MOD<<endl;//这样既然是对的,那么上面也是对的
}
}
else// m == 1
{
cout<<dp[n][]<<endl;
}
// for(int i=1;i<=n-2;i++)
// save[n][i][1] += 2*save[n-2][i][0]+2*save[n-2][i][1];
//
// for(int i=1;i<=n;i++)
// cout<<i<<" "<<save[n][i][1]<<endl;
}
return ;
}

hdu2587(递推)的更多相关文章

  1. 【BZOJ-2476】战场的数目 矩阵乘法 + 递推

    2476: 战场的数目 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 58  Solved: 38[Submit][Status][Discuss] D ...

  2. 从一道NOI练习题说递推和递归

    一.递推: 所谓递推,简单理解就是推导数列的通项公式.先举一个简单的例子(另一个NOI练习题,但不是这次要解的问题): 楼梯有n(100 > n > 0)阶台阶,上楼时可以一步上1阶,也可 ...

  3. Flags-Ural1225简单递推

    Time limit: 1.0 second Memory limit: 64 MB On the Day of the Flag of Russia a shop-owner decided to ...

  4. 利用Cayley-Hamilton theorem 优化矩阵线性递推

    平时有关线性递推的题,很多都可以利用矩阵乘法来解决. 时间复杂度一般是O(K3logn)因此对矩阵的规模限制比较大. 下面介绍一种利用利用Cayley-Hamilton theorem加速矩阵乘法的方 ...

  5. 【66测试20161115】【树】【DP_LIS】【SPFA】【同余最短路】【递推】【矩阵快速幂】

    还有3天,今天考试又崩了.状态还没有调整过来... 第一题:小L的二叉树 勤奋又善于思考的小L接触了信息学竞赛,开始的学习十分顺利.但是,小L对数据结构的掌握实在十分渣渣.所以,小L当时卡在了二叉树. ...

  6. 简单递推 HDU-2108

    要成为一个ACMer,就是要不断学习,不断刷题...最近写了一些递推,发现递推规律还是挺明显的,最简单的斐波那契函数(爬楼梯问题),这个大家应该都会,看一点稍微进阶了一点的,不是简单的v[i] = v ...

  7. [ACM_动态规划] 数字三角形(数塔)_递推_记忆化搜索

    1.直接用递归函数计算状态转移方程,效率十分低下,可以考虑用递推方法,其实就是“正着推导,逆着计算” #include<iostream> #include<algorithm> ...

  8. 矩阵乘法&矩阵快速幂&矩阵快速幂解决线性递推式

    矩阵乘法,顾名思义矩阵与矩阵相乘, 两矩阵可相乘的前提:第一个矩阵的行与第二个矩阵的列相等 相乘原则: a b     *     A B   =   a*A+b*C  a*c+b*D c d     ...

  9. openjudge1768 最大子矩阵[二维前缀和or递推|DP]

    总时间限制:  1000ms 内存限制:  65536kB 描述 已知矩阵的大小定义为矩阵中所有元素的和.给定一个矩阵,你的任务是找到最大的非空(大小至少是1 * 1)子矩阵. 比如,如下4 * 4的 ...

随机推荐

  1. BEGINNING SHAREPOINT&#174; 2013 DEVELOPMENT 第14章节--使用Office Services开发应用程序 新的机器翻译服务

    BEGINNING SHAREPOINT® 2013 DEVELOPMENT 第14章节--使用Office Services开发应用程序  新的机器翻译服务         机器翻译服务也是继Wor ...

  2. S6:组合模式 Composite

    将对象组合成树形结构以表示整体-部分的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性. UML: 示例代码:透明组合:叶节点和子节点具有相同的接口 abstract class Com ...

  3. 《深入PHP:面向对象、模式与实践》(一)

    第1章  PHP:设计与管理 本章主要介绍了本书有哪些内容. 第2章  PHP与对象 本章总结了PHP面向对象特性的发展过程,逐步介绍对象的概念. PHP/FI:支持变量.关联数组和函数.没有对象. ...

  4. Linux-信号详解

    1.Linux支持的所有信号: $ kill -l ) SIGHUP ) SIGINT ) SIGQUIT ) SIGILL ) SIGTRAP ) SIGABRT ) SIGBUS ) SIGFPE ...

  5. asp.net 复习总结

    1.asp.net页面上格式化时间是:<%# Eval("jsBianhao", "{0:yyyy/MM/dd}")%>

  6. 【ASP.NET MVC系列】浅谈数据注解和验证

    [ASP.NET MVC系列]浅谈数据注解和验证   [01]浅谈Google Chrome浏览器(理论篇) [02]浅谈Google Chrome浏览器(操作篇)(上) [03]浅谈Google C ...

  7. 用gradle把springboot项目打包成jar

    ``` 用gradle把springboot项目打包成jar ```### build.gradle 中添加 buildscript { repositories { mavenLocal() mav ...

  8. Linux LVM逻辑卷配置过程详解(创建、扩展、缩减、删除、卸载、快照创建)(未完)

    转:http://blog.csdn.net/xuanfeng407/article/details/51465472

  9. OPPO.1107刷机笔记

    手动 转移任意APP为系统APP的方法流程简述 宗旨: 保持和系统原本同目录下的文件各种设置(权限,所有者,SE上下文),目录结构保持一致即可! 从 /data/app/里将对应的APP文件移动到 / ...

  10. Atitit.java swing打印功能 api  attilax总结

    Atitit.java swing打印功能 api  attilax总结 1. 打印方式有三种:2 1.1. 一是不经过任何修改,直接调用javascript中的window.print()打印.2 ...