2017.12.24

 简单的动态规划

1.数字三角形(算法引入)

题目描述:下图所示是一个数字三角形,其中三角形中的数值为正整数,现规定从最顶层往下走到最底层,每一步可沿左斜线向下或右斜线向下走。设三角形有n层,编程计算出从顶层到底层的一条路径,使得该路径上的和最大,输出最大值。(n<=100)

思路&&代码(搜索回溯):

最显而易见的思路,既然要求一条最短的路径,最简单的方法就是遍历所有的路径,找到一条最优的。时间复杂度是O(2n)以下是搜索代码。

 1 #include <stdio.h>
 2 #include <math.h>
 3 #include <string.h>
 4 int map[101][101],n;
 5 int count=0,ans=-20180101;
 6 void search(int x,int y){
 7   count+=map[x][y];
 8   if(x==n){
 9     if(count>ans)ans=count;
10   }
11   else{
12   search(x+1,y+1);
13   search(x+1,y);
14   }
15   count-=map[x][y];
16 }
17 int main(){
18   scanf("%d",&n);
19   int i,j;
20   for(i=1;i<=n;i++){
21     for(j=1;j<=i;j++){
22       scanf("%d",&map[i][j]);
23     }
24   }
25   search(1,1);
26   printf("%d\n",ans);
27   return 0;
28 }

View Code

思路&&代码(分治法):

对于任意一个点,我们可以把它的最大值和看成Max(sum[i+1][j],[i+1][j+1]),分解为两个规模更小的子问题。但是本质上和搜索没有区别,所以时间复杂度还是O(2n)。

 1 #include <stdio.h>
 2 #include <math.h>
 3 #include <string.h>
 4 int n,map[101][101];
 5 int fenzhi(int x,int y){
 6   if(x==n)return map[x][y];
 7   int zi1,zi2,_max;
 8   zi1=fenzhi(x+1,y);
 9   zi2=fenzhi(x+1,y+1);
10   if(zi1<=zi2)_max=zi2;
11   else           _max=zi1;
12   return _max+map[x][y];
13 }
14 int main(){
15   scanf("%d",&n);
16   int i,j;
17   for(i=1;i<=n;i++){
18     for(j=1;j<=i;j++){
19       scanf("%d",&map[i][j]);
20     }
21   }
22   printf("%d",fenzhi(1,1));
23   return 0;
24 }

View Code

思路&&代码(记忆化):

比搜索要更优。我们注意到,不管是搜索还是分治,它们都是O(2n)的时间复杂度,是因为它们算了一些重复的东西。既然有重复,那我就把这些重复算的东西用一个数组保存起来,要用时就不用再去算一遍,只要调用了。所以把时间复杂度大大提升了,只有O(n2)了。

 1 #include <stdio.h>
 2 #include <math.h>
 3 #include <string.h>
 4 int map[101][101],book[101][101];
 5 int n;
 6 int max(int x,int y){
 7   if(y>x)
 8     return y;
 9   else
10     return x;
11 }
12 int search(int r,int c){
13   int ans;
14   if (r==n) return map[r][c];
15   if (book[r+1][c]==-1)
16     book[r+1][c]=search(r+1,c);
17   if (book[r+1][c+1]==-1)
18     book[r+1][c+1]=search(r+1,c+1);
19   ans=max(book[r+1][c],book[r+1][c+1])+book[r][c];
20   return ans;
21 }
22 int main(){
23   scanf("%d",&n);
24   int i,j;
25   for(i=1;i<=n;i++){
26     for(j=1;j<=i;j++){
27       scanf("%d",&map[i][j]);
28       book[i][j]=-1;
29     }
30   }
31   printf("%d",search(1,1));
32   return 0;
33 }

View Code

思路&&代码(动态规划):

自底向上。第i层的任意一个点,其最大值是它自己加上它下一层的两个点的最大值之和。用i表示行,j表示列,状态转移方程如下。这样,时间复杂度也只有O(2n)。

 1 #include <stdio.h>
 2 #include <math.h>
 3 #include <string.h>
 4 int map[101][101],book[101][101];
 5 int max(int x,int y){
 6   if(x>y)return x;
 7   else   return y;
 8 }
 9 int main(){
10   int n;
11   scanf("%d",&n);
12   int i,j;
13   for(i=1;i<=n;i++){
14     for(j=1;j<=i;j++){
15       scanf("%d",&map[i][j]);
16     }
17   }
18   for(j=1;j<=n;j++)
19     book[n][j]=map[n][j];
20   for(i=n-1;i>=1;i--)
21     for(j=1;j<=i;j++)
22         book[i][j]=max(book[i+1][j+1],book[i+1][j])+map[i][j];
23        printf("%d",book[1][1]);
24   return 0;
25 }

View Code

2.最长上升子序列

思路:

对于以第i个数为右端点的一个序列,他本身就是一个长度为1的上升子序列。这时,如果它的右边有比它数值更小的数,这时的最长上升子序列就是这个元素本身的长度1和以他前面的比他数值更小的这个元素为右端点的最长上升子序列的长度和。

状态转移方程:sum[i]=_Max(sum[i],sum[j]+1);  (j<i,num[j]<num[i])

核心代码:

 1 sum[1]=1;
 2     for(i=2;i<=n;i++){
 3         sum[i]=1;
 4         for(j=1;j<i;j++){
 5             if(num[j]<num[i]){
 6                 sum[i]=_Max(sum[i],sum[j]+1);
 7             }
 8         }
 9     }
10     for(i=1;i<=n;i++)
11         max=_Max(max,sum[i]);

View Code

状态:AC

转载于:https://www.cnblogs.com/yzyl-Leo-wey/p/8167768.html

2018.01.01(数字三角形,最长上升子序列等)相关推荐

  1. 算法知识之最长公共子序列问题(动态规划)

    最近朋友让帮做个关于动态规划的最长公共子序列的问题,翻看以前的笔记并完成该题后,顺便写这样一篇文章,希望对大家有所帮助,同时也帮助自己回顾该知识点. 一.最长公共子序列的定义 子序列:若给定序列X={ ...

  2. python实现求解最长公共子序列LCS问题

    在实现论文<Automatically Generating Models for Botnet Detection>论文的算法中,用到了一个The longest commom subs ...

  3. ACwing 895 - 最长上升子序列(最长上升子序列模型)

    给定一个长度为N的数列,求数值严格单调递增的子序列的长度最长是多少. 输入格式 第一行包含整数N. 第二行包含N个整数,表示完整序列. 输出格式 输出一个整数,表示最大长度. 数据范围 1 ≤ N ≤ ...

  4. 个人笔记:算法讲座3.1——地精的帽子(最长上升子序列)

    本文仅供参考学习使用,谢谢 目录 问题描述: 分析思路: 算法描述: 测试数据: 问题描述: Alice和Bob抓住了一些地精,用魔法把它们栓在了一根长长的竹竿上,每个地精都戴着不同颜色的帽子,而且身 ...

  5. 动态规划之最长公共子序列问题

    问题描述 若给定序列X={x1,x2,-,xm},则另一序列Z={z1,z2,-,zk},是X的子序列是指存在一个严格递增下标序列{i1,i2,-,ik}使得对于所有j=1,2,-,k有:zj=xij ...

  6. 数字三角形,最长上升子序列,背包模型 AcWing算法提高课 (详解)

    目录 数字三角形模型(只能向右和向下或向左和向上) AcWing 1015. 摘花生 AcWing 1018. 最低通行费(曼哈顿距离-向右和向下-求最小值-初始化) AcWing 1027. 方格取 ...

  7. Haproxy(三)详细记录 2018年01月05日 16:47:36

    Haproxy(三)详细记录 2018年01月05日 16:47:36 阅读数:361 一.各种负载均衡 1.1 tcp反向代理 tcp 22端口反向代理: # vim /etc/haproxy/ha ...

  8. 最长子序列和 动态规划python_算法基础之python实现动态规划中数字三角形和最长上升子序列问题...

    数字三角形问题:python 问题描述:函数 问题分析:spa 程序代码:(递归法和动归法)code # -*- coding: utf-8 -*- """ Create ...

  9. 动态规划之01背包问题和三角形问题

    01背包问题 有N件物品和一个容量为V的背包.第i件物品的费用是c[i],价值是w[i].求解将哪些物品装入背包可使价值总和最大. 这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放. ...

最新文章

  1. mysql 安装 se_mysql的安装过程
  2. 前端性能优化 Web前端应该从哪些方面来优化网站?
  3. LNMP环境添加第三方模块
  4. 飞鸽传书举一个小例子
  5. 【快讯】JeecgBoot低代码平台,成功入选2021科创中国·开源创新榜
  6. 【Elasticsearch】 6 种 能使 es 挂掉的方法
  7. 果汁飞溅海报还不会玩?先从临摹学习PSD分层模板开始
  8. java.net.BindException: Address already in use解决方法
  9. 2019-06-04 Sublime Text 中文输入法的问题
  10. 领导让我接私活,怎么办
  11. java的list和map区别,list和map的区别是什么
  12. 在word中插入参考文献角标
  13. Apache监控之MPM配置
  14. Less系列之导入(Importing)
  15. 计算机如何算幂函数,幂函数(乘方)|指数(函数)|对数(函数)|及其运算法则...
  16. dpdk:vfio-pci模式下iommu(N+Y)-Huge配置-numa配置
  17. 本地html如何封装成app,新手适用:如何把网页快速封装成APP
  18. Java:Windows 10下载和配置JDK
  19. [JavaWeb开发中]HTTP 协议的基本格式和Fiddler抓包工具
  20. HDU4417_树状数组加离线

热门文章

  1. 江苏计算机三级偏软怎么学,计算机三级偏软
  2. 【软件设计师】2020-08-05
  3. 【算法竞赛学习】气象海洋预测-Task4 模型建立之 TCNN+RNN
  4. 【图像超分辨率】Understanding Deformable Alignment in Video Super-Resolution
  5. java有password_hash吗,java 实现 PHP password_hash() password_verify() 单向验证
  6. 『设计模式』设计模式--策略模式
  7. 图论--Floyd总结
  8. codeforce 227D Naughty Stone Piles (贪心+递归+递推)
  9. POJ1088 滑雪题解+HDU 1078(记忆化搜索DP)
  10. Matlab 卷积函数 ——conv2