前言:最近刷了一些水題…
CH5E26
題意:一副不含王的撲克牌由52張牌組成,由紅桃、黑桃、梅花、方塊4組牌組成,每組13張不同的面值。現在給定 52 張牌中的若干張,請計算將它們排成一列,相鄰的牌面值不同的方案數
計數 dp
考慮到剩 1 張花色,剩 2 張花色 … 本質是一樣的
令 fa,b,c,d 表示還剩 a 種剩一個花色的,b 種剩兩個花色的
如果選一個只剩一種花色的
fa,b,c,d=a∗fa−1,b,c,d
選剩兩種花色的
fa,b,c,d=2∗b∗fa+1,b−1,c,d
等等,好像會算重
考慮上一次選的什麼,發現與這一層有關的,只與上一層剩幾個花色有關
如果上一層選的剩 3 種花色的,那麼這一層就有一種 2 種花色的不能選
於是記錄 las
fa,b,c,d=(a−[las=2])∗fa−1,b,c,d
fa,b,c,d=2∗(b−[las=3])∗fa+1,b−1,c,d
fa,b,c,d=3∗(c−[las=4])∗fa,b+1,c−1,d
fa,b,c,d=4∗d∗fa,b,c+1,d−1
HDU 2196
給一棵樹,求從每一個點出發的最長距離 n≤1e5
先做一遍樹形 dp,求出每個點向下的最長路徑
考慮從祖先轉移過來的,爲 max ( 祖先向下的最長路,祖先繼續向上的最長路)
等等,好像出鍋了,如果祖先向下的最長就是自己呢
於是還要處理出次長鏈,兩次 dp 就可以了
IOI 2000 郵局
題意:選出 m 個郵局,n 個村莊,每個村莊會走到離它最近的郵局,問總代價的最小值
暴力轉移:
fi,j=fk,j−1+cost(k+1,i)
首先有一個不是正解的東西:
考慮到選的郵局越多就一定越優,於是可以讓每選一個郵局就加上一個 mid,然後二分 mid 直到選出來的個數正好是 m,俗稱 dp 凸優化
正解:四邊形不等式
感性理解:令 fi,j 的決策點爲 pi,j,則 pi,j−1≤pi,j≤pi+1,j
因爲如果少了一個郵局,就更加分散,決策點更靠前
所有當前的決策點在 [pi,j−1,pi+1,j],對複雜度的貢獻就是 pi+1,j−pi,j−1,求個和可以證明是 O(nm)
POJ 1191
拆方差
∑i=1n(xi−x)2=n∗x2+∑i=1nxi2−2∗n∗x2
需要最小化 ∑i=1nxi2
fx1,y1,x2,y2,k 表示當前矩陣,還可以分割 k 次的最小代價
枚舉橫切還是豎切,記憶化搜索
POJ 1390
題意:給你一個顏色塊序列,每次你可以刪除一些相同顏色並且相鄰的顏色塊,並獲得刪除數目平方的收益,現在給你一個顏色塊序列,問收益最大是多少?
挺好的題,比較容易想到區間 dp,fl,r 表示區間 [l,r] 的最優方案
發現沒法轉移,考慮加維度
fl,r,k 表示 [l,r],r 後有 k 個更它顏色相同的塊的最優方案
枚舉當前是見好就收還是放手一搏
fl,r,k=max(fl,r−1,0+k2,fl,p,cntp+k+fp+1,r−1,0)(colp=coli)
POJ 2288
題意:給出 n 個點,m 條邊。每個點有一個權值 w。找出一條漢密爾頓路徑,使它的值最大
一條漢密爾頓路徑的值由三部分組成:
路徑上每個點的權值之和
路徑上每條邊u-v,將其權值的積累加起來。即 w[u]∗w[v]
如果三個點形成一個三角形,例如 i,i+1,i+2,那麼將w[i]∗w[i+1]∗w[i+2]累加起
考慮如何加入三角形的貢獻,需要加兩維,fS,i,j 表示當前狀態,上一個是 i,上上個是 j 的最大貢獻
枚舉下一個轉移即可
POJ 2374
自己寫的時候從上往下 dp,細節有點多,其實可以倒過來,從下往上走
dpi,0/1 表示走到第 i 層,在左 / 右端點的最小長度
顯然只能由它的端點往下走碰到的第一塊來轉移
於是走過一塊就在線段樹上更新,權值爲它的層數,轉移的時候線段樹上查一個 max 即可
POJ 3252
數位dp,fi,j,k 表示到了第 i 位,有 j 個 0,k 個 1 的個數
前導 0 不能算到 0 的貢獻裏,記憶化搜索就過了
POJ 3709
首先如果要縮一段的話,一定縮成開頭
fi 表示縮到 i 的最小代價,枚舉從哪一個開始縮
fi=min(fj+sumi−sumj−(i−j)∗aj+1)
斜率優化即可
SCOI 2010 股票交易
fi,j 表示到第 i 天,有 j 份股票的最大收益,枚舉從哪一天轉移,當前是買進還是買出,轉移前的股票數
買進:fi,j=max(fp,k−(j−k)∗api)(p∈[1,i−w−1],k∈[j−asi,j))
賣出:fi,j=max(fp,k+(k−j)∗bpi)(p∈[1,i−w−1],k∈(j,j+bsi])
p 用前綴 max,每次 fi,j=max(fi,j,fi−1,j) 即可
然後括號拆開就可以單調隊列了
CF1103D Professional layer
題意簡述:給 n 個二元組和一個 k。 二元組 (ai,ei)表示第i個位置的權值是 ai,貢獻是 ei。 現在對於每個位置可以讓它的權值除以它自己一個不超過k的約數,要求從n個數中選擇若干個數出來,使得它們的權值在除以約數過後的 gcd爲 1,花費的代價是選出來的選擇數的個數乘上選出來的所有數的貢獻和
考慮到最後的 gcd 一定是一個不超過 1e12 的數
gcd 可以分解爲不超過 12 個約數
又有狀壓約數集合的影子
令 gcd=p1a1∗p2a2∗...∗pkak
對於一個要記入答案的數 val
令 val=t∗p1b1∗p2b2∗...∗pkbk
我們選了它更優當且僅當它可以把一個或多個 bi 消成 0
這樣一來,每個數至少去掉一個 pi
因此最多選擇 12 個數就可以把 gcd 消爲 1
令 fi,S 表示選了 i 個數,已經消去的 gcd 的集合爲 S 的方案數
然後就可以枚舉超集轉移
CF1106E Lunar New Year and Red Envelopes
fi,j 表示到 i,干擾了 j 次的最小貢獻
枚舉當前幹不幹擾轉移即可,預處理 nxti 表示 i 能轉移到哪裏
fi,j+w[i]−−−fnxt[i],j
fi,j−−−fi+1,j+1
CF1111D Destroy the Colony
發現如果不限制的話 ans=fn/2∗∏cnti(n/2)!∗(n/2)!
fi 表示用所有數組成 i 的方案數,可以揹包
考慮預處理答案,每次強制兩個不選,然後做一遍,複雜度 O(523∗n)
然後學了一個叫揹包回退的東西
void ins(int x){ for(int i = n/2; i >= x; i--) Add(f[i], f[i-x]);}
void del(int x){ for(int i = x; i <= n/2; i++) Del(f[i], f[i-x]);}
插兩個數的答案時暴力刪除,變成了 O(522∗n)
小總結:
總的來說還是一些比較基礎的模板類的題
主要複習了一下:
計數 dp,數位 dp,單調隊列,斜率優化,狀壓
區間 dp,數據結構優化,樹形 dp
對四邊形不等式的套路有了一些理解
然後有幾道巧妙的加狀態的題
見識了一些揹包回退
深化了狀壓質因數的套路
在狀態定義上的功夫還差得遠…