NOIP Dp基本套路大全

2021-08-10 07:09:18 字數 3608 閱讀 7969

dp,一直是困擾許(我)許(這)多(一)多(個)oler(蒟蒻)的問題之一。而在看似毫無章法與固定解題模式的dp題中,卻實實在在有那麼一些基本套路,幫助我們在求解dp的過程中能給我們或多或少提(多)供(騙)一些思(水)路(分)。

持續更新中。。。求大佬指正orz。

p.s:(以下的狀態轉移方程只是最基礎的,不含其他優化)

題意

詢問你兩個字串的最長公共子串行。

狀態轉移方程

for(int i=1;i<=n;i++)

for(int j=1;j<=m;j++)

if(s1[i]==s2[j])f[i][j]=f[i-1][j-1]+1;

else f[i][j]=max(f[i-1][j],f[i][j-1]);

// 預處理: 無

// i: 列舉到的s1串的位置

// j: 列舉到的s2串的位置

// 時間複雜度:n*m

例題

hdu 5495

hdu 1503

題意

詢問你乙個數列的最長不下降子串行

(拓展):乙個數列能拆城的最少的不下降子串行個數。

狀態轉移方程(?)

for(int i=1;i<=n;i++)

if(left>ans) ans++;

num[left]=a[i];

} cout

// 二分+貪心,每次每次把同一位替換成更小的數。

// 時間複雜度:n*log(n)

for(int i=1;i<=n;i++)

// 預處理:dp[1,2][1~n]=1

// dp[1]-- i:當前列舉的第i個數字

// dp[2]-- i:當前列舉的第i個數字(拓展)

// 時間複雜度:n^2

例題

hdu 1257

hdu 1025

題意

給你一系列的區間,詢問你最多能安排多少區間,使他們的交集為空(不

發生衝突)。

狀態轉移方程

for(int i=1;i<=n;i++)

// 預處理: 將所有區間以結束時間為第一關鍵字從小到大排序。

// i: 列舉到第幾個區間

// 時間複雜度:n

p.s:事實上也可以貪心做。。。

例題

hdu 5495

hdu 1503

題意

給你乙個數列,詢問你整個數列的最大區間和 或者 指定區間長度的最大區間和。

狀態轉移方程

//整個數列的最大區間和

for(int i=1;i<=n;i++)

// i:列舉到的數在數列中的位置

// 時間複雜度:n

//整個數列的最大區間和

//字首和版本(不算優化吧。。。)

for ( int i = 1 ; i <= n ; i++ )

// i:列舉到的數在數列中的位置

// 時間複雜度:n

//指定區間長度k的最大值(區間長度小於等於k)

//單調佇列優化

for(i=1;i<=n;i++)

}// ans:最大和 ans1:區間起點 ans2:區間終點

// i:列舉到的數在數列中的位置

// 時間複雜度:n

hdu 3415

hdu 1231

題意

給你乙個矩陣,詢問你子矩陣中和為k的倍數的矩陣個數 或者 和為特定值的矩陣的個數

狀態轉移方程

//字首和被特定值(q)整除的個數【正整數】 

hash[0]=1;

for(int i=1;ifor(int j=i+1;j<=m;j++)

// i,j:列舉 長/寬

// k:列舉 行數/列數

// 雜湊儲存字首和,方便判斷。

// 時間複雜度:n*n*m或者n*m*m

//字首和為特定值(q)的個數【正整數】 

hash[0]=1;

for(int i=1;ifor(int j=i+1;j<=m;j++)

for(int k=1;k<=n;k++)

hash[sum[k][j]-sum[k][i]]--;

}// i,j:列舉 長/寬

// k:列舉 行數/列數

// 雜湊儲存字首和,方便判斷。

// 時間複雜度:n*n*m或者n*m*m

以下揹包問題可參考部落格:

(1)題意

給你一堆資料,每種資料只有乙個,有空間與價值兩個資料,問你在指定的空間內能獲得多大的價值。

狀態轉移方程

for(int i=1;i<=n;i++)

// 預處理:無

// i:第i件物品

// j:剩餘空間大小

// 時間複雜度:n*m

p.s:重點:從後往前列舉

例題

hdu 3466

hdu 2955

題意

給你一堆資料,每種資料有無數個,有空間與價值兩個資料,問你在指定的空間內能獲得多大的價值。

狀態轉移方程

for(int i=1;i<=n;i++)

// 預處理:無

// i:第i件物品

// j:剩餘空間大小

// 時間複雜度:n*m

p.s:重點:從前往後列舉

例題

hdu 2602

hdu 1114

題意

給你一顆樹,每個節點可以控制與自己距離為k的節點,詢問控制所有的邊所需要的最少節點數 或者 控制所有的點所需要的最少節點數。

p.s:此類題事實上可能用貪心更快更準。。。

狀態轉移方程

//每個節點可以控制與自己距離為1的節點

//詢問控制所有的邊所需要的最少節點數

void dfs(int root)

}// 預處理:root,fa[i],son[i],bro[i]

// ans = min(dp[root][0],dp[root][1])

// 0/1:不選/選擇這個點

// root:以這個節點為根的子數

// 時間複雜度:。。。。。。

Redis使用基本套路

redis的資料,通常都是來自於資料庫。存入redis當中,可以快速的查詢。不用每次都關聯查詢,然後其他處理什麼的。通常可以把一些,不經常變的資料儲存其中。避免資料變動,而redis快取資料不變,可以為快取資料設定乙個過期時間。通常redis儲存的資料都是陣列進行json加密,而取出的時候,進行js...

基本套路選講

這道題明顯就是乙個大暴力,但是考場上碰到這種題確實讓人傷腦筋,如何在考場上穩穩地拿下這100分呢?首先,為了進行完全的搜尋,這題應用dfs的結構,而不是貪心選擇某種出牌方式。然後我們應先分析搜尋的方法。在dfs中我們先考慮不帶牌的出法。即單順子,雙順子,三順子。三帶一 三帶二可以看做是特殊的三張牌 ...

luogu 十一 基本套路 day1

對於乙個線段,要不就只買票,要不就用ic卡 貪心嘛 所以只要比較這兩種策略,取較大值就好。rep i,1,n 1 rd n rd m while m rep i,1,n rep j,1,n 構造相鄰的兩頭牛,看能不能貪心,且看需要滿足什麼條件的時候才能貪心。設有相鄰的兩頭牛a,b,來討論一下在滿足什...