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,來討論一下在滿足什...