六級第一關——下樓梯

上目錄:

目錄

題目描述

輸入格式

輸出格式

輸入輸出樣例

說明/提示

一、DP的意義以及線性動規簡介

在一個困難的嵌套決策鏈中,決策出最優解。

二、動態規劃性質淺談

三、子序列問題

(一)一個序列中的最長上升子序列(LIS)

1、n^2做法

下一狀態最優值=最優比較函數(已經記錄的最優值,可以由先前狀態得出的最優值)

2、n^log(n) 做法

(二)兩個序列中的最長公共子序列(LCS)

dp[i][j]=max(dp[i][j],dp[i?1][j?1]+1);

dp[i][j]=max(dp[i?1][j],dp[i][j?1]


你可能很奇怪,為神馬六級第一關是下樓梯?其實你去考場就要下樓梯,呵呵。

不說了,先看看考點:

我們要好好下樓梯,不要學小楊同學這樣下樓梯:

題目描述

小楊發現,下樓梯時每步可以走?1?個臺階、2?個臺階或?3?個臺階。現在一共有?N?個臺階,你能幫小楊算算有多少種下樓梯方案嗎?

輸入格式

輸入一行,包含一個整數?N。

輸出格式

輸出一行一個整數表示答案。

輸入輸出樣例

輸入 #1

4

輸出 #1

7

輸入 #2

10

輸出 #2

274

說明/提示

對全部的測試點,保證?1≤N≤60。

周知眾所,連下兩個或三個臺階會讓小楊滾下樓梯,他不會那么做,故輸出1即可。

題目是題目,現實是現實,你不要搶戲!

動態規劃發自內心的一句話。

上面是有名的一個人——騙分神說的話,大家別當真。

一、DP的意義以及線性動規簡介

動態規劃自古以來是DALAO凌虐萌新的分水嶺,但有些OIer認為并沒有這么重要——會打暴力,大不了記憶化。但是其實,動態規劃學得好不好,可以彰顯出一個OIer的基本素養——能否富有邏輯地思考一些問題,以及更重要的——能否將數學、算籌學(決策學)、數據結構合并成一個整體并且將其合理運用

而我們首先要了解的,便是綜合難度在所有動規題里最為簡單的了。線性動規既是一切動規的基礎,同時也可以廣泛解決生活中的各項問題——比如我們需要決策在相同的時間內做價值盡量大的事情,該如何決策,最優解是什么——這就引出了動態規劃的真正含義:

在一個困難的嵌套決策鏈中,決策出最優解。

二、動態規劃性質淺談

首先,動態規劃和遞推有些相似(尤其是線性動規),但是不同于遞推的是:

遞推求出的是數據,所以只是針對數據進行操作;而動態規劃求出的是最優狀態,所以必然也是針對狀態的操作,而狀態自然可以出現在最優解中,也可以不出現——這便是決策的特性。

其次,由于每個狀態均可以由之前的狀態演變形成,所以動態規劃有可推導性,但同時,動態規劃也有無后效性,即每個當前狀態會且僅會決策出下一狀態,而不直接對未來的所有狀態負責,可以理解為未來與過去無關。

三、子序列問題

(一)一個序列中的最長上升子序列(LIS)

例:由6個數,分別是: 1 7 6 2 3 4,求最長上升子序列。

評析:首先,我們要理解什么叫做最長上升子序列:1、最長上升子序列的元素不一定相鄰 2、最長上升子序列一定是原序列的子集。所以這個例子中的LIS就是:1 2 3 4,共4個

1、n^2做法

首先我們要知道,對于每一個元素來說,最長上升子序列就是其本身。那我們便可以維護一個dp數組,使得dp[i]表示以第i元素為結尾的最長上升子序列長度,那么對于每一個dp[i]而言,初始值即為1.

那么dp數組怎么求呢?我們可以對于每一個i,枚舉在i之前的每一個元素j,然后對于每一個dp[j],如果元素i大于元素j,那么就可以考慮繼承,而最優解的得出則是依靠對于每一個繼承而來的dp值,取max.

	for(int i=1;i<=n;i++){dp[i]=1;//初始化 for(int j=1;j<i;j++)//枚舉i之前的每一個j if(data[j]<data[i] && dp[i]<dp[j]+1)//用if判斷是否可以拼湊成上升子序列,//并且判斷當前狀態是否優于之前枚舉//過的所有狀態,如果是,則↓ dp[i]=dp[j]+1;//更新最優狀態 }

最后,因為我們對于dp數組的定義是到i為止的最長上升子序列長度,所以我們最后對于整個序列,只需要輸出dp[n](n為元素個數)即可。

從這個題我們也不難看出,狀態轉移方程可以如此定義:

下一狀態最優值=最優比較函數(已經記錄的最優值,可以由先前狀態得出的最優值)

2、n^log(n) 做法

我們其實不難看出,對于n^2做法而言,其實就是暴力枚舉:將每個狀態都分別比較一遍。但其實有些沒有必要的狀態的枚舉,導致浪費許多時間,當元素個數到了100004?100005以上時,就已經超時了。而此時,我們可以通過另一種動態規劃的方式來降低時間復雜度:

將原來的dp數組的存儲由數值換成該序列中,上升子序列長度為i的上升子序列,的最小末尾數值。

這其實就是一種幾近貪心的思想:我們當前的上升子序列長度如果已經確定,那么如果這種長度的子序列的結尾元素越小,后面的元素就可以更方便地加入到這條我們臆測的、可作為結果、的上升子序列中。

一定要好好看注釋啊!

3、路徑

只要記錄前驅,然后遞歸輸出即可(也可以用棧)

下面貼出完整代碼

#include <iostream>
using namespace std;
const int MAXN = 1000 + 10;
int n, data[MAXN];
int dp[MAXN]; 
int from[MAXN]; 
void output(int x)
{if(!x)return;output(from[x]);cout<<data[x]<<" ";//迭代輸出 
}
int main()
{cin>>n;for(int i=1;i<=n;i++)cin>>data[i];// DPfor(int i=1;i<=n;i++){dp[i]=1;from[i]=0;for(int j=1;j<i;j++)if(data[j]<data[i] && dp[i]<dp[j]+1){dp[i]=dp[j]+1;from[i]=j;//逐個記錄前驅 }}int ans=dp[1], pos=1;for(int i=1;i<=n;i++)if(ans<dp[i]){ans=dp[i];pos=i;//由于需要遞歸輸出//所以要記錄最長上升子序列的最后一//個元素,來不斷回溯出路徑來 }cout<<ans<<endl;output(pos);return 0;
}

(二)兩個序列中的最長公共子序列(LCS)

1、譬如給定2個序列:

1 2 3 4 53 2 1 4 5

試求出最長的公共子序列。

顯然長度是3,包含3??4??5?三個元素(不唯一)

解析:我們可以用dp[i][j]來表示第一個串的前i位,第二個串的前j位的LCS的長度,那么我們是很容易想到狀態轉移方程的:

如果當前的A1[i]和A2[j]相同(即是有新的公共元素) 那么

dp[i][j]=max(dp[i][j],dp[i?1][j?1]+1);

如果不相同,即無法更新公共元素,考慮繼承:

dp[i][j]=max(dp[i?1][j],dp[i][j?1]

那么代碼:

#include<iostream>
using namespace std;
int dp[1001][1001],a1[2001],a2[2001],n,m;
int main()
{//dp[i][j]表示兩個串從頭開始,直到第一個串的第i位 //和第二個串的第j位最多有多少個公共子元素 cin>>n>>m;for(int i=1;i<=n;i++)scanf("%d",&a1[i]);for(int i=1;i<=m;i++)scanf("%d",&a2[i]);for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){dp[i][j]=max(dp[i-1][j],dp[i][j-1]);if(a1[i]==a2[j])dp[i][j]=max(dp[i][j],dp[i-1][j-1]+1);//因為更新,所以++; }cout<<dp[n][m];
}

2、而對于洛谷P1439而言,不僅是卡上面的樸素算法,也考察到了全排列的性質:

對于這個題而言,樸素算法是n^2的,會被10^5卡死,所以我們可以考慮nlogn的做法:

因為兩個序列都是1?n的全排列,那么兩個序列元素互異且相同,也就是說只是位置不同罷了,那么我們通過一個map數組將A序列的數字在B序列中的位置表示出來——

因為最長公共子序列是按位向后比對的,所以a序列每個元素在b序列中的位置如果遞增,就說明b中的這個數在a中的這個數整體位置偏后,可以考慮納入LCS——那么就可以轉變成nlogn求用來記錄新的位置的map數組中的**LIS**。

最后貼n^log(n)代碼:

#include<iostream>
#include<cstdio>
using namespace std;
int a[100001],b[100001],map[100001],f[100001];
int main()
{int n;cin>>n;for(int i=1;i<=n;i++){scanf("%d",&a[i]);map[a[i]]=i;}for(int i=1;i<=n;i++){scanf("%d",&b[i]);f[i]=0x7fffffff;}int len=0;f[0]=0;for(int i=1;i<=n;i++){int l=0,r=len,mid;if(map[b[i]]>f[len])f[++len]=map[b[i]];else {while(l<r){	mid=(l+r)/2;if(f[mid]>map[b[i]])r=mid;else l=mid+1; }f[l]=min(map[b[i]],f[l]);}}cout<<len;return 0
}

那么,這個題怎么解?

顯然,設dp[i]為下到第i級臺階時的走法數,則有dp[i]=dp[i-1]+dp[i-2]+dp[i-3];

dp[0]=1;不走也是一種走法

dp[1]=1;

dp[2]=2;

dp[3]=4;

好啦,你過了六級的第一關!不過是不是有跳關通道?我不知道啊。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/98785.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/98785.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/98785.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【Linux基礎】Linux系統配置IP詳解:從入門到精通

目錄 1 Linux網絡配置概述 2 網卡配置文件位置和命名規則 2.1 配置文件位置 2.2 網卡命名規則 2.3 配置文件命名示例 3 網卡配置文件詳解 3.1 主要參數說明 4 Linux系統配置IP步驟 4.1 DHCP動態配置 4.2 靜態IP配置 5 Linux網絡配置流程 5.1 網絡配置流程 5.2 網卡…

C語言sprintf的高效替代方案

C語言的sprintf和snprintf將變量格式化輸出到內存buffer&#xff0c;其功能強大&#xff0c;用起來很方便。但sprintf系列函數的運行效率低下&#xff0c;主要包括四方面的原因&#xff1a;格式字符串解析、變參處理、locale&#xff08;本地化&#xff09;支持和通用&#xff…

【知識堂】制造業與物流數字化全景圖:系統縮寫大全與專業名詞速查手冊

前言在制造業和物流行業的數字化轉型過程中&#xff0c;我們經常會接觸到大量的 系統縮寫&#xff08;如 ERP、MES、WMS…&#xff09;和 專業名詞&#xff08;如 AGV、BOM、LOT…&#xff09;。 這些縮寫往往讓剛入行的人“一頭霧水”&#xff0c;即使是有經驗的從業者&#x…

利用JSONCrack與cpolar提升數據可視化及跨團隊協作效率

文章目錄前言1. 在Linux上使用Docker安裝JSONCrack2. 安裝Cpolar內網穿透工具3. 配置JSON Crack界面公網地址4. 遠程訪問 JSONCrack 界面5. 固定 JSONCrack公網地址前言 JSONCrack 是一款功能強大的開源數據可視化工具&#xff0c;專為解析和展示復雜的 JSON、XML 等結構化數據…

CANoe入門之一 CANoe功能概述

01 CANoe功能概述 CANoe軟件在汽車電子領域被廣泛應用。 CANoe軟件的全稱是CAN Open Environment&#xff0c;它是一個專業的系統級總線和ECU仿真、分析、開發、測試工具。支持ECU或總線網絡開發從需求分析到系統實現的全過程&#xff0c;包括模型創建、仿真、測試、診斷及通信…

項目管理核心八項(軟件篇)

2025年09月11日23:50:33&#xff1a;進來常思&#xff0c;寫代碼也五六年了&#xff0c;后面的路該何去何從呢&#xff1f; 項目管理核心八項一、項目管理之“建立開發人員 backup 機制”二、待補充一、項目管理之“建立開發人員 backup 機制” “建立開發人員 backup 機制” 是…

springboot redisson 分布式鎖入門與實戰

Spring Boot3 Redisson 項目地址 https://gitee.com/supervol/loong-springboot-study &#xff08;記得給個start&#xff0c;感謝&#xff09; Redisson 介紹 在分布式系統中&#xff0c;多節點部署的應用對共享資源&#xff08;如數據庫記錄、緩存鍵、文件&#xff09;的…

使用 Tkinter + Requests 實現地理信息安全系統學習時長助手

?重磅&#xff01;盹貓的個人小站正式上線啦&#xff5e;誠邀各位技術大佬前來探秘&#xff01;? 這里有&#xff1a; 硬核技術干貨&#xff1a;編程技巧、開發經驗、踩坑指南&#xff0c;帶你解鎖技術新姿勢&#xff01;趣味開發日常&#xff1a;代碼背后的腦洞故事、工具…

構建一個優雅的待辦事項應用:現代JavaScript實踐

構建一個優雅的待辦事項應用&#xff1a;現代JavaScript實踐本文將介紹如何使用現代JavaScript&#xff08;ES6&#xff09;和DOM操作創建一個功能完整的待辦事項應用&#xff0c;無需任何外部庫或框架。功能概述添加新任務標記任務為完成/未完成編輯任務內容刪除任務過濾任務&…

【數據可視化-111】93大閱兵后的軍費開支情況———2024年全球軍費開支分析:用Python和Pyecharts打造炫酷可視化大屏

&#x1f9d1; 博主簡介&#xff1a;曾任某智慧城市類企業算法總監&#xff0c;目前在美國市場的物流公司從事高級算法工程師一職&#xff0c;深耕人工智能領域&#xff0c;精通python數據挖掘、可視化、機器學習等&#xff0c;發表過AI相關的專利并多次在AI類比賽中獲獎。CSDN…

3.2.Maven-概述-介紹安裝

一.介紹&#xff1a;二.安裝&#xff1a;Maven的安裝比較簡單&#xff0c;因為他是綠色版的軟件&#xff0c;官方給我們提供Maven的安裝包就是一個zip壓縮包&#xff0c;在進行Maven安裝以及配置的時候&#xff0c;主要進行如下4步操作&#xff1a;第一步&#xff1a;把官方提供…

Kafka面試精講 Day 14:集群擴容與數據遷移

【Kafka面試精講 Day 14】集群擴容與數據遷移 在“Kafka面試精講”系列的第14天&#xff0c;我們將深入探討 Kafka 運維中最關鍵的操作之一&#xff1a;集群擴容與數據遷移。隨著業務增長&#xff0c;原始 Kafka 集群可能面臨磁盤不足、吞吐瓶頸或節點負載不均等問題&#xff…

字節一面 面經(補充版)

什么是RabbitMQ&#xff0c;特點是什么怎么理解保障消息的一致性String、StringBuffer、StringBuilder解釋一下線程安全先操作數據庫再刪緩存還是先刪緩存再操作數據庫這種辦法能杜絕數據不一致問題嗎解釋一下AOP介紹Redis的特點&#xff08;Redis比較快&#xff09;Redis為什么…

【MFC】對話框屬性:Absolute Align(絕對對齊)

前言 本文介紹對話框屬性中的Absolute Align(絕對對齊)&#xff0c;同時給出相關示例便于理解。 目錄1 位置2 詳解3 示例1 位置 首先介紹一下這個屬性在哪里。 在資源視圖中雙擊對話框節點&#xff0c;打開該對話框&#xff1b; 鼠標右鍵工作區空白處&#xff0c;單擊屬性&…

【從0開始學習Java | 第17篇】集合(中-Set部分)

文章目錄Java集合之Set&#xff1a;無序不重復的元素容器一、Set接口的核心特性二、常用實現類及底層原理1. HashSet&#xff1a;基于哈希表的高效實現2. LinkedHashSet&#xff1a;保留插入順序的哈希實現3. TreeSet&#xff1a;基于紅黑樹的排序實現三、實現類對比與選擇建議…

玩轉Docker | 使用Docker部署dufs文件管理工具

玩轉Docker | 使用Docker部署dufs文件管理工具 前言 一、 dufs介紹 Dufs簡介 核心特性 ?? 靜態文件服務 ?? 文件夾打包下載 ?? 拖拽上傳文件/文件夾 ?? 文件在線創建、編輯與搜索 ? 斷點續傳與部分傳輸 ?? 細粒度訪問控制 ?? HTTPS 安全傳輸 ?? WebDAV 兼容支持…

【混合開發】vue+Android、iPhone、鴻蒙、win、macOS、Linux之android 把assert里的dist.zip 包解壓到sd卡里

一圖勝千言 上一篇有 <!-- 讀寫外部存儲 --> <uses-permission android:name"android.permission.WRITE_EXTERNAL_STORAGE"android:maxSdkVersion"28"/> <uses-permission android:name"android.permission.READ_EXTERNAL_STORAGE&qu…

線程的創建.銷毀

線程線程的創建在 C 中&#xff0c;線程的創建核心是通過std::thread類實現的&#xff0c;其構造函數需要傳入一個可調用對象&#xff08;Callable Object&#xff09;作為線程入口。可調用對象包括普通函數、lambda 表達式、函數對象&#xff08;functor&#xff09;、類的成員…

MySQL基礎全面解析

MySQL作為最流行的關系型數據庫管理系統之一&#xff0c;是每一位開發者必備的核心技能。本文將系統性地解析MySQL的基礎知識&#xff0c;結合關鍵概念與實戰應用&#xff0c;幫助您構建扎實的數據庫基礎。1. SQL與NoSQL的本質區別SQL&#xff08;結構化查詢語言&#xff09;數…

4、幽絡源微服務項目實戰:后端公共模塊創建與引入多租戶模塊

前言 上節我們將電網巡檢系統的前端vue2項目創建、配置&#xff0c;并構建了最基礎的多租戶界面&#xff0c;本節來繼續構建后端的公共模塊、多租戶模塊&#xff0c;并將公共模塊引入到多租戶模塊中。 創建公共模塊和多租戶模塊 在back父工程下創建兩個Module&#xff0c;和…