首页 > 其他分享 >杭电OJ 2084 数塔

杭电OJ 2084 数塔

时间:2024-03-28 22:13:06浏览次数:26  
标签:结点 OJ 数塔 int arr 杭电 MAXN answer dp

数塔
题目明确告诉你,这是一道DP动态规划问题,那么首先先回顾什么是动态规划,就是把原问题分解为多个子问题,再记忆子问题的结果,来降低时间复杂度。

观察这个数塔,首先设置一个数组dp[][],令\(dp[j][i]\)表示以第j层的第i个结点为终点的最大和,有以下3种情况:

  • 1.边界情况,结点\(i == 0\)或者结点\(i == j\),此时只有不断向上一条路;

  • 2.当结点i属于当前层次的中间的结点位置,那么\(dp[j][i] = arr[j][i] + max(dp[j-1][i-1], dp[j-1][i])\);

得到状态转移方程之后,我们只需遍历求出以最后一层的每个结点为终点的最大值,然后输出其中的最大值即可。

AC代码如下:

//2024-03-28
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int MAXN = 100 + 2;
int arr[MAXN][MAXN];

int dp[MAXN][MAXN];
//第j层的第i个结点为终点的最大和 递归+记忆化
int Function(int i, int j) {
    if(dp[j][i] != -1) {
        return dp[j][i];
    }
    int answer;
    if(i == 0 && j == 0) {//递归出口
        answer = arr[j][i];
    } else{
        answer = arr[j][i] + max(Function(i-1, j-1), Function(i, j-1));
    }
    dp[j][i] = answer;
    return answer;
}
int main() {
    int c, n;
    cin >> c;
    while(c--) {
        cin >> n;
        for(int i = 0; i < n; ++i) {
            for(int j = 0; j <= i; ++j) {
                cin >> arr[i][j];
            }
        }
        memset(dp, 0, sizeof(dp));
        for(int j = 1; j < n; ++j) { //j层i个结点
            for(int i = 1; i < j; ++i) {
                dp[j][i] = -1; 
            }
        }
        for(int j = 0; j < n; ++j) { //边界情况
            for(int k = 0; k <= j; ++k) {
                dp[j][0] += arr[k][0];
                if(j != 0) dp[j][j] += arr[k][k];
            }
        }
        int maximum = -INT_MAX;
        for(int i = 0; i < n; ++i) {
            maximum = max(maximum, Function(i, n-1));
        }
        cout << maximum << endl;
    }
    return 0;
}

标签:结点,OJ,数塔,int,arr,杭电,MAXN,answer,dp
From: https://www.cnblogs.com/paopaotangzu/p/18102735

相关文章

  • 挑战程序设计竞赛 2.6章习题 poj 3421 X-factor Chains
    https://vjudge.net/problem/POJ-3421#author=GPT_zhGivenapositiveintegerX,anX-factorchainoflengthmisasequenceofintegers,1=X0,X1,X2,…,Xm=XsatisfyingXi<Xi+1andXi|Xi+1wherea|bmeansaperfectlydividesintob.Nowwea......
  • 合肥工业大学oj-4014 ch4-4.车辆问题
    描述一个停车场里只停三轮车和四轮小汽车,共有m辆,轮子有n个。输入m和n的值,编程求出三轮车和小汽车各有多少辆?输入两个正整数,车辆总数m和轮子个数n,m和n均小于10000。输出三轮车和四轮小汽车的数量,以空格分开。如果无解,输出-1-1输入样例11040输出样例1010输入样......
  • [题解] BZOJ4203 同桌的你
    题意给出\(n\)个人的性别\(b_i\)、喜欢的人\(a_i\)(有且仅有一个)。现在两人分一组,若一组中存在一人喜欢另一人,则称这一组为「满意」的。要求在最大化「满意」组数的前提下最大化男女同桌组数,并构造分组方案。思路考虑建图,从\(i\)到\(a_i\)连一条有向边,转化为基环树上......
  • 北林oj数据结构259
    字符串的插入描述编写算法,实现下面函数的功能。函数voidinsert(char*s,char*t,intpos)将字符串t插入到字符串s中,插入位置为pos(插在第pos个字符前)。假设分配给字符串s的空间足够让字符串t插入。(说明:不得使用任何库函数)输入多组数据,每组数据有三行,第一行为插入的位置pos......
  • C++ | 剪枝(DFS)lanqiao OJ 2942
     上一篇我们已经分享了DFS的学习,剪枝相当于对部分DFS进行优化正常用DFS写,会遍历每一种情况,因此要判断他的合法性,并且在第十个检测点会超时,用剪枝后,这道题就可以过啦。//不剪枝的方法#include<bits/stdc++.h>usingnamespacestd;constintN=15;inta[N],n;v......
  • BZOJ2908 又是nand
    BZOJ2908又是nand首先手玩需要计算的值,发现既不满足交换律也不满足结合律,不好维护。对于位运算,常见的考虑分开每一位计算贡献,对于单独一位,计算较为简单。既然计算的值只能按顺序计算,那我们只能考虑树剖(其他数据结构不好维护顺序)。给每一位建一棵线段树,在线段树上维护。注意到......
  • 【CUMTOJ】法师康工人(代码细节控制)
    题目描述代码#include<bits/stdc++.h>usingnamespacestd;classworker{ public: intstart; intend; worker(){ } worker(inta,intb){ start=a;end=b; }};boolcmp(workerw1,workerw2){ returnw1.start<w2.start;}intmai......
  • 最近的学习笔记YBTOJ
    写在前面:洛谷月赛太烂了,或者说,效率太低了,所以来写总结你好!开学了,平凡的我回到了平凡的世界不得不承认,在学校还是很好的不仅有生活,还有OI最近的OI学习总是围绕着数据结构这个我最烂的板块来讲不知道是不是对我不努力的报复有两位巨佬停课了,实名表示羡慕语文作业是真的不想......
  • CMU15445 2022fall project3
    CMU154452022fallproject3project3相对project2的b+树来说简单太多了,整体没有什么痛苦的debug,基本就看看其他算子的实现参考一下,很快就能写出来。Task1-AccessMethodExecutorsSeqScan首先我们需要知道:init是做一些初始化工作的,next是留给上层节点调用的,SeqScanExecuto......
  • Microsoft办公软件全家桶下载,office/visio/project百度云资源
    Office/visio/project均是由Microsoft公司开发的一套办公软件套装。它包括多个应用程序,主要用于处理办公室中的各种任务,如文字处理、电子表格、演示文稿、电子邮件和数据库管理等。Office2021更新最大的前五个功能:Excel中的动态数组(一个公式返回多个单元格)Excel中的XLO......