【蓝桥杯集训26】线性DP(4 / 4)
创始人
2025-06-01 04:30:28

目录

898. 数字三角形 + 输出最优路径

895. 最长上升子序列 

897. 最长公共子序列

1051. 最大的和 - 前后缀分解dp


898. 数字三角形 + 输出最优路径

活动 - AcWing

题目:

给定如下图所示的数字三角形,从顶部出发,在每一结点可以选择移动至其左下方的结点或移动至其右下方的结点,一直走到底层,要求找出一条路径,使路径上的数字的和最大。

        73   88   1   02   7   4   4
4   5   2   6   5

思路:

从底向上枚举,这样不用判断边界问题

在每个小三角形分支中,顶上的累加其下端两分支的最大值,则最优解就是顶部f[1][1]

import java.util.*;class Main
{static int N=510;static int[][] f=new int[N][N];public static void main(String[] args){Scanner sc=new Scanner(System.in);int n=sc.nextInt();for(int i=1;i<=n;i++) //枚举层数for(int j=1;j<=i;j++) f[i][j]=sc.nextInt();for(int i=n-1;i>=1;i--) //从底向上for(int j=1;j<=i;j++)f[i][j]+=Math.max(f[i+1][j],f[i+1][j+1]);System.out.print(f[1][1]);}
}

输出最优路径:

用map存两个坐标间的指向

import java.util.*;class Main
{static int N=510;static int[][] f=new int[N][N],a=new int[N][N];public static void main(String[] args){Scanner sc=new Scanner(System.in);int n=sc.nextInt();Map mp=new HashMap<>();for(int i=1;i<=n;i++) //枚举层数for(int j=1;j<=i;j++) a[i][j]=f[i][j]=sc.nextInt();for(int i=n-1;i>=1;i--) //从底向上for(int j=1;j<=i;j++){int t=Math.max(f[i+1][j],f[i+1][j+1]);List top=new LinkedList<>();List tt=new LinkedList<>();top.add(i); top.add(j);if(t==f[i+1][j]) {tt.add(i+1); tt.add(j);mp.put(top,tt);}else{tt.add(i+1); tt.add(j+1);mp.put(top,tt);}f[i][j]+=t;}int nx=1,ny=1;List res=new LinkedList<>();while(nx!=n&&ny!=n){res.add(a[nx][ny]);List list=new LinkedList<>();list.add(nx); list.add(ny);List t=mp.get(list);nx=t.get(0); ny=t.get(1);}res.add(a[nx][ny]);System.out.println(f[1][1]);System.out.print(res);}
}

895. 最长上升子序列 

活动 - AcWing

题目:

给定一个长度为 N 的数列,求数值严格单调递增的子序列的长度最长是多少。

思路:

  • 定义f[i]为以下标i结尾的最长上升子序列长度
  • 遍历每个i前面的点j,如果满足a[j]
  • 最后res取所有f[i]中的最大值
import java.util.*;class Main
{static int N=1010;static int[] f=new int[N],a=new int[N];public static void main(String[] args){Scanner sc=new Scanner(System.in);int n=sc.nextInt();//定义f[i]为以下标i结尾的最大上升子序列值for(int i=1;i<=n;i++) a[i]=sc.nextInt();for(int i=1;i<=n;i++){f[i]=1; //只有a[i]一个for(int j=1;j

 

897. 最长公共子序列

 活动 - AcWing

题目

给定两个长度分别为 N 和 M 的字符串 A 和 B,求既是 A 的子序列又是 B 的子序列的字符串长度最长是多少

思路:

定义f[i][j]为a的前i个字母b的前j个字母的最长公共子序列长度

集合划分依据:以a[i],b[j]是否包含在子序列中为依据,可划分成4部分:

  • a[i]不在,b[j]不在 —— f[i-1][j-1]
  • a[i]在,b[j]不在 
  • 不能完全由f[i][j-1]表示,因为f[i][j-1]表示的是a的前i个字母和b的前j-1个字母中最长公共子序列的长度,但b[j]可能存在也可能不存在
  • 但仍然可以用f[i][j-1]表示,因为"a[i]在,b[j]不在"的情况包含在f[i][j-1]中,而求max,对最终结果不影响
  • 例如:要求a,b,c的最大值可以这样求:max(max(a,b),max(b,c)),虽然b被重复使用,但仍能求出max,求max只要保证不漏即可
  • a[i]不在,b[j]在 —— 原理同上,f[i-1][j]
  • a[i]在,b[j]在 —— f[i-1][j-1]+1

实际上,第一种情况包含在第二三情况中

import java.util.*;class Main
{static int N=1010;static int[][] f=new int[N][N];public static void main(String[] args){Scanner sc=new Scanner(System.in);int n=sc.nextInt(),m=sc.nextInt();String a=" "+sc.next();String b=" "+sc.next();for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){f[i][j]=Math.max(f[i-1][j],f[i][j-1]);if(a.charAt(i)==b.charAt(j)) f[i][j]=f[i-1][j-1]+1;}System.out.print(f[n][m]);}
}

 

1051. 最大的和 - 前后缀分解dp

1051. 最大的和 - AcWing题库

题目:

对于给定的整数序列,找出两个不重合连续子段,使得两子段中所有数字的和最大,输出最大值

1
10
1 -1 2 2 3 -3 4 -4 5 -5

在样例中,我们取{2,2,3,-3,4}和{5}两个子段,即可得到答案

思路:

定义f[i]为【1~i】区间内连续和的最大值

定义g[i]为【i~n】区间内连续和的最大值

以f[i]为例:以是否包含a[i]划分集合

  • 不包含a[i]:f[i-1]
  • 包含a[i]:以a[i-1]结尾的最大连续区间和 + a[i]

对前缀f[i]和后缀g[i]进行处理

最后枚举1~n每个间断点,求最大值res即可

import java.util.*;class Main
{static int N=50010;static int[] f=new int[N],g=new int[N];public static void main(String[] args){Scanner sc=new Scanner(System.in);int t=sc.nextInt();while(t-->0){int n=sc.nextInt();int[] a=new int[n+1];for(int i=1;i<=n;i++) a[i]=sc.nextInt();Arrays.fill(f,-0x3f3f3f3f);Arrays.fill(g,-0x3f3f3f3f);int s=0;for(int i=1;i<=n;i++){s=Math.max(0,s)+a[i];     //s维护以a[i-1]结尾的最大连续和 这也是包含a[i]的情况//s=0+a[i]时,相当于以a[i-1]结尾的最大连续和只包含a[i]//s=s+a[i]时,相当于以a[i-1]结尾的最大连续和包含a[i]和之前的最大连续和f[i]=Math.max(f[i-1],s);  //max(不包含a[i],包含a[i])}s=0;for(int i=n;i>=1;i--){s=Math.max(0,s)+a[i];g[i]=Math.max(g[i+1],s);}int res=-0x3f3f3f3f;for(int i=1;i<=n;i++) res=Math.max(res,f[i]+g[i+1]);System.out.println(res);}}
}

 

相关内容

热门资讯

中外对话丨中外专家警告:日本主...   中新网北京12月15日电 题:中外专家警告:日本主动调整军事战略,或走向穷兵黩武  作者 管娜 ...
夏某某(男,大专学历)隐瞒精神... 转自:扬子晚报2024年参军入伍后在安徽出现精神类障碍被退回,2025年隐瞒病史后入伍再被退兵……1...
告别纸上谈兵!AI 培训找哪个...   炒股就看金麒麟分析师研报,权威,专业,及时,全面,助您挖掘潜力主题机会! (来源:雷达财经)“...
一图读懂vivo S50:田曦...   炒股就看金麒麟分析师研报,权威,专业,及时,全面,助您挖掘潜力主题机会! (来源:快科技)快科...
监管部门出手整治不正当价格行为... 近日,国家市场监督管理总局研究起草了《汽车行业价格行为合规指南(征求意见稿)》(下称《指南》),并向...