http://acm.hdu.edu.cn/showproblem.php?pid=2084

题意:

        7
      3      8
    8     1       0
  2       7     4       4
4    5    2       6        5
在上面的数字三角形中寻找一条从顶部到底边的路径,使得路径上所经过的数字之和最大。
路径上的每一步都只能往左下或右下走。只需要求出这个最大和即可,不必给出具体路径。
 
解法1:dfs搜索每一条路径,可以发现很多点会重复搜索。时间复杂度为:O(2的n次方)
//#include <bits/stdc++.h>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <string>
#include <stdio.h>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <string.h>
#include<time.h>
#include <vector>
#define ME(x , y) memset(x , y , sizeof(x))
#define SF(n) scanf("%d" , &n)
#define rep(i , n) for(int i = 0 ; i < n ; i ++)
#define INF 0x3f3f3f3f
#define mod 20191117
#define PI acos(-1)
using namespace std;
typedef long long ll ;
int a[109][109];
int n ; int getsum(int i , int j)
{
if(i == n)
return a[i][j];
else{
int x = getsum(i+1 , j);
int y = getsum(i+1 , j+1);
return max(x , y) + a[i][j];
}
} int main()
{
/*#ifdef ONLINE_JUDGE
#else
freopen("D:/c++/in.txt", "r", stdin);
freopen("D:/c++/out.txt", "w", stdout);
#endif*/
int t ;
scanf("%d" , &t);
while(t--)
{
memset(dp , -1 , sizeof(dp));
scanf("%d" , &n);
for(int i = 1 ; i <= n ; i++)
{
for(int j = 1 ; j <= i ; j++)
{
scanf("%d" , &a[i][j]);
}
}
cout << getsum(1 , 1) << endl ; } return 0;
}

解法1改进:记忆化搜索,将搜索过的点记录下来。时间复杂度O(n的平方)。

//#include <bits/stdc++.h>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <string>
#include <stdio.h>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <string.h>
#include<time.h>
#include <vector>
#define ME(x , y) memset(x , y , sizeof(x))
#define SF(n) scanf("%d" , &n)
#define rep(i , n) for(int i = 0 ; i < n ; i ++)
#define INF 0x3f3f3f3f
#define mod 20191117
#define PI acos(-1)
using namespace std;
typedef long long ll ;
int a[109][109];
int n ;
int dp[109][109]; int getsum(int i , int j)
{
if(i == n)
return a[i][j];
else{
if(dp[i][j] != -1) return dp[i][j];
int x = getsum(i+1 , j);
int y = getsum(i+1 , j+1);
dp[i][j] = max(x,y)+a[i][j];
return max(x , y) + a[i][j];
}
return dp[i][j] ;
} int main()
{
/*#ifdef ONLINE_JUDGE
#else
freopen("D:/c++/in.txt", "r", stdin);
freopen("D:/c++/out.txt", "w", stdout);
#endif*/
int t ;
scanf("%d" , &t);
while(t--)
{
memset(dp , -1 , sizeof(dp));
scanf("%d" , &n);
for(int i = 1 ; i <= n ; i++)
{
for(int j = 1 ; j <= i ; j++)
{
scanf("%d" , &a[i][j]);
}
}
cout << getsum(1 , 1) << endl ;
} return 0;
}

解法2、递归转为递推。从底层向上递推。

//#include <bits/stdc++.h>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <string>
#include <stdio.h>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <string.h>
#include<time.h>
#include <vector>
#define ME(x , y) memset(x , y , sizeof(x))
#define SF(n) scanf("%d" , &n)
#define rep(i , n) for(int i = 0 ; i < n ; i ++)
#define INF 0x3f3f3f3f
#define mod 20191117
#define PI acos(-1)
using namespace std;
typedef long long ll ;
int a[109][109];
int n ;
int dp[109][109]; int main()
{
/*#ifdef ONLINE_JUDGE
#else
freopen("D:/c++/in.txt", "r", stdin);
freopen("D:/c++/out.txt", "w", stdout);
#endif*/
int t ;
scanf("%d" , &t);
while(t--)
{
memset(dp , -1 , sizeof(dp));
scanf("%d" , &n);
for(int i = 1 ; i <= n ; i++)
{
for(int j = 1 ; j <= i ; j++)
{
scanf("%d" , &a[i][j]);
}
}
for(int i = 1 ; i <= n ; i++)
{
dp[n][i] = a[n][i];
}
for(int i = n - 1 ; i >= 1 ; i--)
{
for(int j = 1 ; j <= i ; j++)
{
dp[i][j] = max(dp[i+1][j] , dp[i+1][j+1])+a[i][j];
}
}
cout << dp[1][1] << endl ;
} return 0;
}

解法2优化空间

//#include <bits/stdc++.h>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <string>
#include <stdio.h>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <string.h>
#include<time.h>
#include <vector>
#define ME(x , y) memset(x , y , sizeof(x))
#define SF(n) scanf("%d" , &n)
#define rep(i , n) for(int i = 0 ; i < n ; i ++)
#define INF 0x3f3f3f3f
#define mod 20191117
#define PI acos(-1)
using namespace std;
typedef long long ll ;
int a[109][109];
int n ;
int dp[109]; int main()
{
/*#ifdef ONLINE_JUDGE
#else
freopen("D:/c++/in.txt", "r", stdin);
freopen("D:/c++/out.txt", "w", stdout);
#endif*/
int t ;
scanf("%d" , &t);
while(t--)
{
memset(dp , -1 , sizeof(dp));
scanf("%d" , &n);
for(int i = 1 ; i <= n ; i++)
{
for(int j = 1 ; j <= i ; j++)
{
scanf("%d" , &a[i][j]);
}
}
for(int i = 1 ; i <= n ; i++)
{
dp[i] = a[n][i];
}
for(int i = n - 1 ; i >= 1 ; i--)
{
for(int j = 1 ; j <= i ; j++)
{
dp[j] = max(dp[j] , dp[j+1])+a[i][j];
}
}
cout << dp[1] << endl ;
} return 0;
}

dp入门题(数塔)的更多相关文章

  1. 【dp入门题】【跟着14练dp吧...囧】

    A HDU_2048 数塔 dp入门题——数塔问题:求路径的最大和: 状态方程: dp[i][j] = max(dp[i+1][j], dp[i+1][j+1])+a[i][j];dp[n][j] = ...

  2. poj 3254 状压dp入门题

    1.poj 3254  Corn Fields    状态压缩dp入门题 2.总结:二进制实在巧妙,以前从来没想过可以这样用. 题意:n行m列,1表示肥沃,0表示贫瘠,把牛放在肥沃处,要求所有牛不能相 ...

  3. POJ 2342 树形DP入门题

    有一个大学的庆典晚会,想邀请一些在大学任职的人来參加,每一个人有自己的搞笑值,可是如今遇到一个问题就是假设两个人之间有直接的上下级关系,那么他们中仅仅能有一个来參加,求请来一部分人之后,搞笑值的最大是 ...

  4. (树形DP入门题)Anniversary party(没有上司的舞会) HDU - 1520

    题意: 有个公司要举行一场晚会.为了让到会的每个人不受他的直接上司约束而能玩得开心,公司领导决定:如果邀请了某个人,那么一定不会再邀请他的直接的上司,但该人的上司的上司,上司的上司的上司等都可以邀请. ...

  5. 数字三角形/数塔问题(DP入门题)

    有形如下图所示的数塔,从顶部出发,在每一结点可以选择向左走或是向右走,一起走到底层,要求找出一条路径,使路径上的值最大. 样例输入: 5 13 11 8 12 7 26 6 14 15 8 12 7 ...

  6. HDU2084 数塔 (DP入门题)

    数塔 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submissi ...

  7. HDU 2089 不要62【数位DP入门题】

    不要62 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  8. Hdu-1565 方格取数(1) (状态压缩dp入门题

    方格取数(1) Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total S ...

  9. hdu_Anniversary party_(树形DP入门题)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1520 题意:有N个人,N-1个人有自己的上司,每个人有一个快乐值,如果这个人参加了聚会,那么这个人的直 ...

随机推荐

  1. C# 两个进程之间通讯(管道通信 )

    #region  客户端        NamedPipeClientStream pipeClient =        new NamedPipeClientStream("localh ...

  2. Springboot 解决跨域请求

    Cors处理 跨域请求 细粒度 直接在controller层上 添加@CrossOrigin注解 @PostMapping("/") @CrossOrigin(value = &q ...

  3. 【UOJ#129】 【NOI2015】寿司晚宴

    题目描述 为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿司晚宴.小 G 和小 W 作为参加 NOI 的选手,也被邀请参加了寿司晚宴. 在晚宴上,主办方为大家提供了 n−1 种不同的寿司,编号 ...

  4. CentOS7 服务器上如何安装python3

    1.官网下载python3的源码包 网址:https://www.python.org/ 进去之后点击导航栏的Downloads,也可以鼠标放到Downloads上弹出菜单选择Source code, ...

  5. 官网Windows 10安装程序驱动下载--截止:2019.01.06版本

    说明:鉴于win7,8不可直接再下载原装iOS文件,这份共享程序包是为以后N年做的准备.如果N年后这个包还可以用,就可以省去很多麻烦. 百度网盘分享:https://pan.baidu.com/s/1 ...

  6. Hibernate动态条件查询(Criteria Query)

    1.创建一个Criteria实例net.sf.hibernate.Criteria这个接口代表对一个特定的持久化类的查询.Session是用来制造Criteria实例的工厂. Criteria cri ...

  7. java 判断Map集合中包含指定的键名,则返回true,否则返回false。

    public static void main(String[] args) { Map map = new HashMap(); //定义Map对象 map.put("apple" ...

  8. C++入门经典-例2.5-使用附加格式说明scanf函数的格式输入

    1:代码如下: // 2.5.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" int main() { long iLong; /*长整型变 ...

  9. JavaWeb之上传与下载

    文件上传概述: 1,文件上传对页面的要求: 必须使用表单,而不能是超链接 表单的method必须是post 表单的enctype必须是multipart/form-data 在表单中添加file表单字 ...

  10. Python对字典分别按键(key)和值(value)进行排序

    使用sorted函数进行排序 sorted(iterable,key,reverse),sorted一共有iterable,key,reverse这三个参数;其中iterable表示可以迭代的对象,例 ...