动态规划的核心就是状态和状态转移方程。

对于该题,需要用抽象的方法思考,把当前的位置(i,j)看成一个状态,然后定义状态的指标函数d(i,j)为从格子出发时能得到的最大和(包括格子本身的值)。

在这个状态定义下,原问题的解就是d(i,j).

下面看一下不同状态之间如何转移。从格子(i,j)出发有两种策略。如果向左走,则到(i+1,j)后需要求“从(i+1,j)出发能得到的最大和”这一问题,即d(i+1,j)。

类似的,往右走之后需要求解d(i+1,j+1).由于可以在这两个决策中自由选择,所以应选择其中较大者。换句话说就是得到状态转移方程

d(i,j)=a(i,j)+Max(d(i+1,j),d(i+1,j+1))

这样就保证了子树的最优,这个性质称为最优子结构。

用直接递归的方法计算状态转移方程,效率往往十分低下。其原因是相同的子问题被重复计算了多次。

因此我们对其优化采用了递推算法或者采用记忆搜索的方式。

递推计算就是把每个问题直接罗列出来,因此不会重复。

记忆搜索的程序依然是递归的,但是把计算结果放在了数组d中。开始将所有状态置为-1,只要是计算过的状态就就变成非负,因此只要判断是否d[i][j]>=0,就知道它是否计算过。

#include<iostream>
#include<string>
using namespace std;
void input(int a[][10],int n)
{
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<=i;j++)
        {
            cin>>a[i][j];
        }
    }
}
int max(int a,int b)
{
    if(a>b)
        return a;
    else
        return b;
}
/*******************i表示当前行数,j表示当前列数,n表示规格****************************/
/**********d(i,j)表示状态,d(i,j)=a(i,j)+Max(d(i+1,j),d(i+1,j+1))为状态转移方程*********/
int d(int a[][10],int i,int j,int n)
{
    if(i>=n)
        return 0;
    else
    {
        return a[i][j]+max(d(a,i+1,j,n),d(a,i+1,j+1,n));
    }
}
/**************采用递推计算,i表示当前行数,j表示当前列数,n表示规格**********************************/
int d1(int a[][10],int n)
{
    int i,j;
    int b[10][10];
    for(i=0;i<=n;i++)
        b[n][i]=0;        //将b(n,0~n)状态全部赋值为0
    for(i=n-1;i>=0;i--)
    {
        for(j=0;j<=i;j++)
        {
            b[i][j]=a[i][j]+max(b[i+1][j],b[i+1][j+1]);
        }
    }
    return b[0][0];
}

/*************采用记忆化搜索*************************/
int d2(int a[][10],int b[][10],int i,int j,int n)
{
    if(b[i][j]>=0)
        return b[i][j];
    else
    {
        if(i>=n)
            return 0;
        else
            return b[i][j]=a[i][j]+max(d2(a,b,i+1,j,n),d2(a,b,i+1,j+1,n));
    }
}
int main()
{

    int a[10][10];
    int b[10][10];
    memset(b,-1,sizeof(b));
    int n;
    cout<<"请输入总共有多少行"<<endl;
    cin>>n;
    input(a,n);
    cout<<d(a,0,0,n)<<endl;
    cout<<d1(a,n)<<endl;
    cout<<d2(a,b,0,0,n)<<endl;
    return 0;
}

动态规划——数字三角形(递归or递推or记忆化搜索)的更多相关文章

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

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

  2. 洛谷 P1464 Function【动态规划(递推)/记忆化搜索(递归)】

    题目描述 对于一个递归函数w(a,b,c) 如果a<=0 or b<=0 or c<=0就返回值1. 如果a>20 or b>20 or c>20就返回w(20,2 ...

  3. luogu P1216 [IOI1994][USACO1.5]数字三角形 Number Triangles (递推)

    链接:https://www.luogu.org/problemnew/show/P1216 题面: 题目描述 观察下面的数字金字塔. 写一个程序来查找从最高点到底部任意处结束的路径,使路径经过数字的 ...

  4. DFS——>记忆化搜索——>动态规划

    以洛谷P1802  5倍经验日 为例 https://www.luogu.org/problem/show?pid=1802 题目背景 现在乐斗有活动了!每打一个人可以获得5倍经验!absi2011却 ...

  5. poj1163The Triangle(动态规划,记忆化搜索)

    7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 (Figure 1) Figure 1 shows a number triangle. Write a program that calc ...

  6. Chapter1 递归与递推

    Chapter 1 递归与递推 时间复杂度(转载自yxc大佬) 一般ACM或者笔试题的时间限制是1秒或2秒. 在这种情况下,C++代码中的操作次数控制在 107107 为最佳. 下面给出在不同数据范围 ...

  7. 由DAG到背包问题——记忆化搜索和递推两种解法

    一.问题描述 物品无限的背包问题:有n种物品,每种均有无穷多个.第 i 种物品的体积为Vi,重量为Wi.选一些物品装到一个容量为 C 的背包中,求使得背包内物品总体积不超过C的前提下重量的最大值.1≤ ...

  8. [每日一题2020.06.14]leetcode #70 爬楼梯 斐波那契数列 记忆化搜索 递推通项公式

    题目链接 题意 : 求斐波那契数列第n项 很简单一道题, 写它是因为想水一篇博客 勾起了我的回忆 首先, 求斐波那契数列, 一定 不 要 用 递归 ! 依稀记得当年校赛, 我在第一题交了20发超时, ...

  9. 【CF607B】Zuma——区间dp(记忆化搜索/递推)

    以下是从中文翻译成人话的题面: 给定一个长度小于等于500的序列,每个数字代表一个颜色,每次可以消掉一个回文串,问最多消几次可以消完? (7.16) 这个题从洛谷pend回来以后显示有103个测试点( ...

随机推荐

  1. Apache+php+mysql win7 64位安装的几个注意事项

    网上一堆安装教程,所以不赘述具体安装过程,只说注意事项.新手推荐phpstudy 如果想单个安装,那么以下是我两三年内多次在win winserver环境下配置Apache环境的一点注意事项,下载连接 ...

  2. The package does not support the device architecture (x86). You can change the supported architectures in the Android Build section of the Project Opt

    The package does not support the device architecture (x86). You can change the supported architectur ...

  3. C语言的本质(29)——C语言与汇编之寄存器和寻址方式

    x86的通用寄存器有eax.ebx.ecx.edx.edi.esi.这些寄存器在大多数指令中是可以任意选用的,比如movl指令可以把一个立即数传送到eax中,也可传送到ebx中.但也有一些指令规定只能 ...

  4. codevs1166 矩阵取数游戏

    题目描述 Description [问题描述] 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m 的矩阵,矩阵中的每个元素aij均 为非负整数.游戏规则如下: 1. 每次取数时须从每行各取走一个 ...

  5. Life is short, you need Python

    今年四五月份的时候我打算学一门计算机语言. 计算机语言实在是很多,选哪一个? 其实这个选择就和去市场买菜类似,想明白了自己的需求才能做好决定.你想做什么饭,就去买什么菜.想做南瓜粥,就要去买南瓜,想要 ...

  6. C和指针 (pointers on C)——第五章:操作符和表达式

    第五章 操作符和表达式 这一章假设没做过玩过单片机.汇编的话,读起来可能比較吃力,尤其是在移位运算符.位运算符应用上.另外多注意一下左值和右值的理解. 总结: 算术操作符.赋值操作符.关系操作符.条件 ...

  7. Linq 中的Select事例

    ---恢复内容开始--- 1.对查询结果进行转换. string[] names={"ADE","Jerry","Steves"}; var ...

  8. div滚动与控制

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><html><head&g ...

  9. UVA 1374 Power Calculus

    题意: 给出m,问对n最少进行几次操作.n初始为1,能得到m.操作1位将n平方.操作2为将n除以之前出现的n值中的任意一个. 分析: 其实是关于指数的操作,即从1到m最少的步数.我们可以先确定最少步数 ...

  10. Gabor滤波器学习

    本文的目的是用C实现生成Gabor模版,并对图像卷积.并简单提一下,Gabor滤波器在纹理特征提取上的应用. 一.什么是Gabor函数(以下内容含部分翻译自维基百科) 在图像处理中,Gabor函数是一 ...