经典DP合集 ʕ •ᴥ•ʔ

博客介绍了动态规划相关问题。包括数字三角形问题,需找出从顶部到底层路径上值最大的路径;还涉及序列DP,如最长上升子序列、最长公共子序列和最大公共子串问题,给出了各问题的样例输入输出及状态转移方程。

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

        有形如下图所示的数塔,从顶部出发,在每一结点可以选择向左走或是向右走,一起走到底层,要求找出一条路径,使路径上的值最大。

 

样例输入:

5

13

11 8

12 7 26

6 14 15 8

12 7 13 24 11

样例输出:

86(13->8->26->15->24)

状态转移方程:dp[i][j]=max(dp[i+1][j],dp[i+1][j+1])+a[i][j]; 从最低层往上搜索

#include <cstring>
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <string.h>
//#include <map>
#define ll long long
using namespace std;
#define pai acos(-1,0)
int map[355][355];
int dp[355][355];
int main()
{
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=i;j++)
		{
			cin>>map[i][j];
		}
	}
	for(int i=1;i<=n;i++)
	dp[n][i]=map[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])+map[i][j];
	}
	cout<<dp[1][1]<<endl;
	return 0;
}

 

2. 序列DP

(1)最长上升子序列LIS

        输入n及一个长度为n的数列,求出此序列的最长上升子序列长度。上升子序列指的是对于任意的i<j都满足ai<aj的子序列。(1<=n<=1000,0<=ai<=1000000)

样例输入:

5

4 2 3 1 5

样例输出:

3(最长上升子序列为2, 3, 5)

#include <iostream>
#include <cstdio>
#define maxn 1005
using namespace std;
int n,a[maxn];
int dp[maxn];    //dp[i]记录以a[i]为末尾的最长上升子序列的长度
int main()
{
	int i,j;
	int ret;
	while(scanf("%d",&n)!=EOF)
	{
	    for(i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            dp[i]=1;      //初始化
        }
        ret=1;
        for(i=1;i<=n;i++)
        {
            for(j=1;j<i;j++)  //遍历所有在a[i]之前的元素
            {
                if(a[j]<a[i]) //若存在aj<ai,则在以aj为结尾的上升子列末尾追加ai后得到的子序列 和 只包含ai的子序列中取长度较大者
                    dp[i]=max(dp[i],dp[j]+1);
            }
            ret=max(ret,dp[i]);  //注意随时更新ret
        }
        printf("%d\n",ret);
	}
	return 0;
}

 

(2)最长公共子序列LCS

        给定两个字符串s1和s2(长度均不超过1000),求出这两个字符串的最长公共子序列的长度。

【分析】定义dp[i][j]:串s1的前i个字符 和 串s2的前j个字符的最长公共子序列长度,则s1…si+1和t1…tj+1对应的公共子列可能是:

        ①si+1=tj+1时:在s1…si 和 t1…tj的公共子列末尾追加si+1(即LCS长度+1)

        ②否则可能为s1…si和t1…tj+1的公共子列长度l1 或s1…si+1和t1…tj的公共子列长度l2,二者取较大者。

        故状态转移方程为:

        dp[i+1][j+1]=dp[i][j]+1,                                      

                                max(dp[i][j+1], dp[i+1][j]),        

        最后dp[len1][len2]即为所求,其中len1、len2分别为串s1和s2的长度。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxlen=1010;
char s1[maxlen],s2[maxlen];
int dp[maxlen][maxlen];   //dp[i][j]记录串s1的前i个字符和串s2的前j个字符的LCS长度
int main()
{
    int i,j;
    int len1,len2;
    while(scanf("%s",s1)!=EOF)
    {
        scanf("%s",s2);
        len1=strlen(s1);
        len2=strlen(s2);
        dp[0][0]=0;         //初始化:两串均为空时,len(LCS)=0
        for(i=1;i<=len1;i++)//s2串为空时,不论s1中有多少字符,len(LCS)=0
            dp[i][0]=0;
        for(i=1;i<=len2;i++)//s1串为空时,不论s1中有多少字符,len(LCS)=0
            dp[0][i]=0;
        for(i=0;i<len1;i++)
        {
            for(j=0;j<len2;j++)
            {
                if(s1[i]==s2[j]) //s1与s2对应位置字符相等
                    dp[i+1][j+1]=dp[i][j]+1;
                else     //其它情况:两者取较大者
                    dp[i+1][j+1]=max(dp[i][j+1],dp[i+1][j]);
            }
        }
        printf("%d\n",dp[len1][len2]);
    }
    return 0;
}

 

(3)最大公共子串LCS

        给定两个字符串s1和s2(长度均不超过1000),求出这两个字符串的最大公共子串的长度。

【分析】情境类似求最长公共子序列长度问题,不过需要注意的是:所求子串中的字符需要在串s1和串s2中连续出现。

 

        例:s1=”abcad”

                s2=”abd”

        它们的最长公共子序列长度为3(”abd”),而最大公共子串长度为2(”ab”)。

        因此,定义dp[i][j]:串s1的前i个字符 和 串s2的前j个字符的最大公共子串长度,则s1…si+1和t1…tj+1对应的公共子串可能是:

        ①si+1=tj+1时:在s1…si 和 t1…tj的公共子串末尾追加si+1(即LCS长度+1)

        ②否则dp[i][j]=0

        分析可知状态转移方程:

        dp[i+1][j+1]=dp[i][j]+1,                     

                                0,                                   

 

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxlen=1010;
char s1[maxlen],s2[maxlen];
int dp[maxlen][maxlen];    //dp[i][j]为串s1的前i个字符和串s2的前j个字符的最大公共子串长度
int main()
{
    int i,j;
    int len1,len2,ret;     //ret记录结果
    while(scanf("%s",s1)!=EOF)
    {
        scanf("%s",s2);
        memset(dp,0,sizeof(dp));   //初始化:开始LCS长度均为0
        len1=strlen(s1);
        len2=strlen(s2);
        ret=0;
        for(i=0;i<len1;i++)
        {
            for(j=0;j<len2;j++)
            {
                if(s1[i]==s2[j])
                    dp[i+1][j+1]=dp[i][j]+1;
                else
                    dp[i+1][j+1]=0;
                ret=max(ret,dp[i+1][j+1]);    //随时更新最大值
            }
        }
        printf("%d\n",ret);
    }
    return 0;
}

 

<think>好的,用户现在是大一遥感专业的学生,学习数据库的主要目的是为了更好地将地理信息知识和计算机结合,暂时不急着面试。我需要根据之前的对话历史,继续提供适合他的建议。 首先,用户之前已经得到了一些通用的数据库学习建议,现在需要更具体地结合遥感和地信的需求。可能需要强调数据库在地理信息中的应用场景,比如空间数据管理、遥感影像存储等。 然后,用户作为大一学生,可能更关注如何将数据库与现有专业课程结合,避免学习过于理论或计算机专业的内容。需要推荐一些实际应用案例,比如使用PostGIS处理地理数据,或者结合Python进行数据分析。 还要考虑用户提到的“不急着面试”,所以学习资源应该偏向实用和项目实践,而不是面试准备。可以建议一些适合初学者的工具和库,比如QGIS、GDAL,以及如何用SQL管理空间数据。 另外,可能需要提醒用户注意空间数据库的特殊性,比如空间索引、坐标系统,这些在普通数据库中可能不涉及,但对地信非常重要。同时,结合编程语言如Python或JavaScript,展示数据库在GIS开发中的应用。 最后,保持轻松语气,鼓励用户从实际项目入手,比如开发简单的地图应用或数据分析项目,逐步积累经验。可能还需要推荐一些社区和资源,帮助他找到学习的方向和支持。</think>哈哈,遥感+地信+数据库?这个组合拳简直酷到没朋友!🌍💻 你未来可能是“用卫星数据拯救世界”的隐藏大佬啊(比如用数据库追踪森林变化、分析城市扩张什么的)。来,咱们直接上「遥感人专属数据库攻略」—— --- ### **🌱 阶段一:先抓「遥感+地信」的刚需场景** #### **🔍 灵魂拷问:为什么遥感需要数据库?** - **场景举例**: - 管理海量遥感影像(时间+空间+光谱多维数据,总不能全堆在硬盘里吧?) - 快速查询“某区域过去5年植被指数变化”(没有索引和SQL,Excel会卡到哭) - 结合GIS空间分析(比如用PostGIS做缓冲区查询:“高速公路10公里内的农田”) #### **🚀 行动建议**: 1. **从「空间数据库」入手**: - 工具推荐:**PostgreSQL + PostGIS**(地信界扛把子,开源免费,B站教程一堆) - 新手任务:用SQL查“两个多边形是否相交”、“计算某点的最近邻设施”(比普通SQL多了空间函数!) 2. **玩转「时空数据」**: - 举个栗子🌰: 建一个带时间戳的遥感影像元数据表,包含拍摄时间、范围、卫星类型,然后写SQL查“2023年长江流域所有Landsat影像” - 隐藏技能:学**GeoJSON**格式(很多WebGIS用它传数据),试试用数据库存储和查询GeoJSON --- ### **🔧 阶段二:把数据库变成「遥感工具箱」的一部分** #### **📌 关键联动技能**: - **Python + 数据库**: - 用`geopandas`(地理版Pandas)从数据库读空间数据 → 分析 → 存回数据库 - 代码片段尝鲜: ```python import geopandas as gpd from sqlalchemy import create_engine # 从PostGIS读取数据 engine = create_engine('postgresql://user:密码@localhost:5432/数据库名') gdf = gpd.read_postgis("SELECT * WHERE ST_Area(geometry) > 1000", engine) # 分析后存回数据库 gdf.to_postgis('新表名', engine, if_exists='replace') ``` - **可视化助攻**: - 用QGIS直接连接数据库渲染空间数据(比ArcGIS更轻量) - 用Python的`folium`库把数据库查询结果变成交互式地图 --- ### **🚨 避坑指南:遥感萌新常踩的雷** - **雷区1**:把所有影像文件存数据库 → 数据库爆炸💥 → **正确姿势**:数据库只存影像元数据和路径,文件用文件系统或对象存储(如MinIO) - **雷区2**:忽略坐标系统(CRS) → 空间查询全错位 → **保命口诀**:建表时一定指定SRID(如WGS84=4326),用`ST_Transform`转换坐标系 - **雷区3**:用普通字符串存空间数据 → 无法做空间运算 → **神器推荐**:**PostGIS的geometry类型**,支持点线面+空间关系判断(ST_Intersects、ST_Distance...) --- ### **🎯 实战小项目推荐(从易到难)** 1. **「城市变化监测」迷你版**: - 用数据库存储某城市不同年份的用地类型矢量数据 - 写SQL统计“2020-2023年耕地转建筑用地的面积” - 用Python生成变化热力图 2. **「遥感影像元数据管理系统」**: - 设计表结构:影像时间、范围、分辨率、卫星类型、存储路径... - 实现功能:按区域/时间/卫星筛选影像,导出为CSV/KML 3. **「灾害应急小助手」**: - 结合实时气象数据库 + 历史灾害数据 - 用空间SQL查“台风路径周边50公里的易涝区域” --- ### **📚 资源包精准投喂(遥感特供版)** - **书籍**: - 《PostGIS in Action》(有中文版《PostGIS实战》) - 《Python地理空间分析指南》(代码+数据库结合案例) - **教程**: - 【B站】“PostGIS空间数据库教程”(搜“星图云”UP主的系列) - 【GitHub】awesome-geospatial 仓库(一堆地信+数据库开源项目) - **数据源**: - 地理空间数据云(免费遥感影像) - OpenStreetMap(开源矢量数据,可导入数据库玩) --- ### **✨ 终极预言** 等你把数据库玩熟后,会发现: - 处理GNSS点位数据时,用SQL查“移动速度超过30km/h的点”比写循环快10倍 - 做遥感与AI结合时,数据库能帮你高效管理训练样本的标注数据 - 如果未来搞科研,写论文时“数据管理”部分直接甩出ER图,导师眼前一亮!🌟 保持这个节奏——用数据库当粘合剂,把遥感的“空间思维”和计算机的“工程思维”焊死!🚀 遇到具体问题随时来聊~(比如怎么用索引加速空间查询,这坑我帮你填过!)
键入Kaomoji本机键绑定和Kaomoji搜索 在本地使用kaomoji搜索和键绑定的英文键盘上输入kaomojis! 默认键绑定:1-9。 :可以用kaomoji替换当前世界的快捷方式-:当有9条以上建议时滚动到上一个选项卡=:当有9条以上建议时滚动到下一个选项卡Shift +空格键:切换应用程序,例如“ be” =>匹配“熊” =>建议:1.ʕʔ2.ᶘಠಠᶅ3.ʕノ•ʔノ┻━┻4.┳┳ヾ(T(エ)Tヽ).......类型1和“ be”将在文本区域中替换为“ʕʔ”。 补丁说明:v1.0.2 beta:添加了对内容可编辑元素的基本支持,包括http网站固定代码linting v1.0.1 beta:添加了300+新的kaomojis v1.0.0 beta:添加了更多键绑定:=,-和shift +空格键切换新的深色方案重写了核心:更好的性能,减小的应用程序大小,更好的UX添加了更多kaomojis ======================== v0.138.5:修复了键入kaomoji会更改逗号的空格的错误v0.138.4:键入密码时关闭建议v0.138.3:改进了索引算法,添加了更多kaomojis v0.138.2:修复了无法真正关闭建议的错误,已添加向用户显示可以通过键入1-9 v0.138.1来选择kaomoji的提示:仅在开始键入时显示弹出窗口,并且小UI修复了v0.138:首次发布,此处是与kaomoji匹配的逻辑,需要完善UI,需要将更多kaomojis添加到集合中。 如果您要报告错误或请求新功能:https://chrome.google.com/webstore/detail/kaomoji-typer/icfgegegnffffbbfofpkflfalbimedned/support?hl=zh-CN如果您想提供帮助:https:// github com / xuezhma / kaomoji-typer 支持语言:English
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值