递归,递推,记忆化搜索,空间优化(数字三角形)

题目链接:http://poj.org/problem?id=1163

1、递归思想:第一层到最底层的最优路径可以分解为:第一层到第二层来,再加上第二层的最优路径

状态: Time Limit Exceeded

#include <algorithm>
#include <stdio.h>
#define MAX 101

using namespace std;

int maps[MAX][MAX];
int n;
int Sum(int i,int j)
{
    if(i==n)
        return maps[i][j];
    else return max(Sum(i+1,j),Sum(i+1,j+1))+maps[i][j];
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=i;j++)
        {
            scanf("%d",&maps[i][j]);
        }
    }
    printf("%d\n",Sum(1,1));
    return 0;
}

2、通过记录表记录每一个点的最优解,从而避免重复计算。

Memory: 332KTime: 0MSLanguage: C++Result: Accepted

#include <iostream>
#include <algorithm>

using namespace std;

const int maxn=105;
int n;
int maps[maxn][maxn];
int maxsum[maxn][maxn];

int Maxsum(int i,int j)
{
    int x,y;
    if(maxsum[i][j]!=-1)
        return maxsum[i][j];
    if(i==n)
        return maps[i][j];
    x=Maxsum(i+1,j);
    y=Maxsum(i+1,j+1);
    maxsum[i][j]=max(x,y)+maps[i][j];
    return maxsum[i][j];
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=i;j++)
        {
            cin>>maps[i][j];
            maxsum[i][j]=-1;
        }
    }
    cout<<Maxsum(1,1)<<endl;
    return 0;
}

3、递归变递推

Memory: 332KTime: 0MSLanguage: C++Result: Accepted

#include <iostream>
#include <algorithm>

using namespace std;

const int maxn=105;
int n;
int maps[maxn][maxn];
int maxsum[maxn][maxn];

int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=i;j++)
        {
            cin>>maps[i][j];
        }
    }
    for(int i=1;i<=n;i++)
        maxsum[n][i]=maps[n][i];
    for(int i=n-1;i>=1;i--)
    {
        for(int j=1;j<=i;j++)
        {
            maxsum[i][j]=max(maxsum[i+1][j],maxsum[i+1][j+1])+maps[i][j];
        }
    }
    cout<<maxsum[1][1]<<endl;
    return 0;
}

4、空间优化,不需要用到二维记录表。

Memory: 204KTime: 0MSLanguage: C++Result: Accepted

#include <stdio.h>
#include <algorithm>
#define MAX 101

using namespace std;

int maps[MAX][MAX];
int sum[MAX];

int main()
{
     int n;
     scanf("%d",&n);
     for(int i=1;i<=n;i++)
     {
         for(int j=1;j<=i;j++)
            scanf("%d",&maps[i][j]);
     }
     for(int i=1;i<=n;i++)
        sum[i]=maps[n][i];
     for(int i=n-1;i>=1;i--)
     {
         for(int j=1;j<=i;j++)
            sum[j]=max(sum[j],sum[j+1])+maps[i][j];
     }
     printf("%d\n",sum[1]);
}
时间: 2024-10-07 23:33:19

递归,递推,记忆化搜索,空间优化(数字三角形)的相关文章

HDU4919 Exclusive or(递推+记忆化搜索+大数)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4919 题意: 给定n求sigma(i^(n - i)) (1<=i<=n-1) 分析: 打表后可以发现规律 1) n = 2 * k + 1; f[n] = 4 * f[k] + 6; 2) n = 2 * k f[n] = 2 * f[k] + 2 * f[k-1] + 4 * k - 4; 具体的证明:http://blog.csdn.net/houserabbit/article/detai

Bailian1664 Placing apples【递推+记忆化递归】

1664:Placing apples 总时间限制: 1000ms 内存限制: 65536kB 描述 We are going to place M same apples into N same plates. There could be some empty plates. How many methods do we have? When we have 7 applesand 3 plates, the methods, (1, 5, 1) and (5, 1, 1) are the

第五第六课------递推+记忆话搜索+搜索八皇后(思想是做梦)+各种剪枝思想

搜索是一个漫长的过程贯彻整个oi: 八皇后------- #include <bits/stdc++.h>#define inf 0x7fusing namespace std;int n,ans,a[inf],b[inf],c[inf],d[inf];void print(){ ++ans; if(ans<=3){ for(int i=1;i<=n;i++) cout<<d[i]<<" "; cout<<endl; }} v

数字三角形——递归、递推、记忆化搜索

数字三角形 描述: 有一个由非负整数组成的三角形,第一行只有一个数,除了最下行之外没个数的左下方和右下方各有一个数. 问题: 从第一行的数开始,每次可以往左下或右下走一格,直到走到最下行,把沿途经过的数全部加起来.如何走才能使得这个和尽量大? 分析: 不难看出此题是一个动态的决策问题:每次有两种选择--左下或右下.如果用回溯法求出所有的可能的路线,就可以从中选出最优的路线.但和往常一样,回溯法的效率太低:一个n层数字三角形的完整路线有2^n条,当n很大时回溯法的速度将让人无法忍受.因此本题讨论用

动态规划&mdash;&mdash;数字三角形(递归or递推or记忆化搜索)

动态规划的核心就是状态和状态转移方程. 对于该题,需要用抽象的方法思考,把当前的位置(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).由于可以在这两个决策中自由选

动态规划 数字三角形(递归,递推,记忆化搜索)

题目要求: 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 在上面的数字三角形中寻找在上面的数字三角形中寻找一条从顶部到底边的路径,使得路径上所经过的数字之和最大.路径上的每一步都只能往左下或右下走.只需要求出这个最大和即可,不必给出具体路径. 三角形的行数大于1小于等于100,数字为 0 - 99 输入格式: 5 //三角形行数.下面是三角形 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 解题思路: 用二维数组存放数字三角形 D[r][j] //表示第i行第j个元素的

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

一.问题描述 物品无限的背包问题:有n种物品,每种均有无穷多个.第 i 种物品的体积为Vi,重量为Wi.选一些物品装到一个容量为 C 的背包中,求使得背包内物品总体积不超过C的前提下重量的最大值.1≤n≤100, 1≤Vi≤C≤10000, 1≤Wi≤1000000. 二.解题思路 我们可以先求体积恰好为 i 时的最大重量(设为d[i]),然后取d[i]中的最大值(i ≤ C).与之前硬币问题,"面值恰好为S"就类似了.只不过加了新属性--重量,相当于把原来的无权图改成带权图,即把&q

hdu4283 You Are the One 区间dp 记忆化搜索or递推

You Are the One Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3032    Accepted Submission(s): 1352 Problem Description The TV shows such as You Are the One has been very popular. In order to

搜索分析(DFS、BFS、递归、记忆化搜索)

搜索分析(DFS.BFS.递归.记忆化搜索) 1.线性查找 在数组a[]={0,1,2,3,4,5,6,7,8,9,10}中查找1这个元素. (1)普通搜索方法,一个循环从0到10搜索,这里略. (2)递归(从中间向两边) 1 //递归一定要写成记忆化递归 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool vis[11]; 5 int count1=0; 6 7 void search(int n){ 8 count1++; 9

【记忆化搜索+优化】10411 - SKAKAVAC

[记忆化搜索+优化]10411 - SKAKAVAC Time Limit: 4000MS Memory Limit: 36000KB 给定一个N-N的矩形,每个格子有一个数字,某人最初在R行C列的位置,他可以按以下规则移动: 1.跳到相邻的行,但列数差要大于1的所有格子.跳到相邻的列,位行数差要大于1的所有格子.即如果当前位置是(r1,c1)要跳到(r2,c2)则它们满足: |r1-r2|=1且|c1-c2|>1或者|c1-c2|=1且|r1-r2|>1 2.目标格子的数字严格大于起跳格子的