寒假的一些筆記
在此對學長們表示深深的敬意……
動態規劃_DP
入門題(DAG_有向無環圖)
POJ 1163 數字三角形
記憶化搜索 or 遞推
POJ 2533 LIS 最長上升子序列
線段樹/樹狀數組
POJ 1458 LCS_最長公共子序列
tyvj 1004 滑雪
記憶化搜索
最長公共上升子序列
揹包
部分揹包、01揹包、無窮揹包(完全揹包)、多重揹包
tyvj 1005
其實簡單來說,方程就是:
線性DP
tyvj 1008 / 1015 / 1124 / 1034
多維DP
POJ 1191 (這題好亂啊啊啊啊啊……)
tyvj 1055 沙子合併
noip 2006 能量項鍊
樹形DP
tyvj 1052 / 1051
POJ 1038 Bugs公司
線段樹+DP
POJ 2374
斜率優化
bzoj 1010
變體樹樹形DP
基環樹DP
bzoj 1791 / 2878
仙人掌DP
bzoj 1023
往年DP
2010.T2 烏龜棋
2010.T4 引水入城
2011.T2 選擇客棧
2012.T3 開車旅行
2013.T3 貨車運輸
2013.T5 花匠
2013.T3 飛揚的小鳥(完全揹包)
2015.T2 子串
分治思想
如:快速排序、歸併排序。
例一:挑芯片
都好都壞扔一個,否則全扔
N爲偶數
i,j,k 所以
奇數
例二:字符串等價問題
a=b 或 分成兩個長度相等的子串,分別判斷
如:abcd 等價於 bacd
這個用
判斷a和b的最小表示是否相同(共有元素)(nlogn)
排序
手寫
*基數排序(nlogn)
個位,十位
插入排序(n^2)
把數字插入到第一個比它大的數前(可以二分出位置)
選擇排序(n^2) ####
在數列中選擇最小的順序排放
冒泡排序(n^2)
前一個大就交換
Δ快速排序(期望 T(n)=2T(n/2)+n=nlogn; 如果恰好選到最大值,T(n)=T(n-1)+n=n^2)
隨機選一個基準值,前排後排(分治思想)
*堆排序
輸出堆頂並刪除
Δ歸併排序(T(n)=2T(n/2)+n=nlogn)
最實用
先將原數列分成兩部分(經典分治思想),再用指針挑小的拿出來
逆序對數量的求法
歸併
第二組與第一組能成逆序對的數量是先於第一組出來的第一組後面元素個數的總和
冒泡
每交換一次相鄰的a[i],a[i+1]就減少恰好一個逆序對,所以交換次數=逆序對數
函數
sort
sort(起點,終點,比較函數);
快速排序,不穩定
priority_queue
priority_queue<int> q;
q.push(); q.pop(); q.top();
優先隊列
數據結構
樹
BST(二叉搜索樹)
左<右
二叉堆(滿足堆性質的完全二叉樹)
哈夫曼樹
-合併果子≈Noi 2015 荷馬史詩
-POJ 1456_sol.2
-POJ 2442
歸併思想(nmlognm)__可用三元組
數學歸納法(nmlogn)
字典樹(trie)
-最大異或值
-POJ 2001 求最短非公共前綴
-POJ 3630 判斷字符串是否爲另一字符串前綴
-BZOJ 2251 輸出出現次數大於1的01串的子串
-POJ 3764 這個太難了……
樹狀數組(BIT)
-POJ 2182
-POJ 2828
-tyvj 1432
線段樹(segment tree)
建樹 修改 查詢 延遲標記 掃描線
-POJ 3468
-tyvj 1038 ST
-tyvj 1039 segment tree
-SPOJ GSS1/GSS3
-POJ 1151
-POJ 1177 求矩形面積∪ 周長∪
-POJ 2482
平衡樹
單旋轉、雙旋轉
treap & splay
哈希
快速判斷兩字符串是否相同
也可在狀態空間大時使用
起始位置開始的爲前綴(hash[i]),後綴同理
hash[i] = (hash[i-1]*k+str[i])%p
(k >= 字符集,取31.131.13131衝突小 ; p取較大的質數,防卡多取
如:98765=(((9*10+8)*10+7)*10+6)*10+5
i~j 的hash值: [hash[j]-hash[i-1]*k^(j-i+1)]%p
最長公共前綴:二分
選取既是前綴又是後綴的最長子串
-兔子的DNA(裸題)
-字符串的排序
用 後綴排序, 稱爲後綴數組
-最長迴文子串
從某一位置向兩邊查詢(二分 + 哈希)
二分是一個非常重要的思想
字符串
strlen(長度) strcpy(複製) strcat(拼接) strcmp(比較) sscanf / sprintf (從字符串中讀取 輸出)
-判斷兩多邊形是否全等
邊權和角分別表示存成字符串
1.最小表示(O(n)) 2.KMP(O(n))
hash
kmp
求T在S中出現的位置
1. 樸素思想:暴力枚舉(n*m)
2. next:用T匹配T自己(錯一位比較,即next[1]=0,j=0)
求next數組的 代碼如下:
next[1]=0;
j=0;
for(int i = 2; i <= m; i++){
while(j && b[j+1] != b[i]) j = next[i];
if(b[j+1] == b[i]) j++;
next[i] = j;
}
-POJ 3461
-POJ 2406
-POJ 2752
最小表示法
-POJ 1635 Subway Tree Systems (判斷兩棵樹是否同構)
最小表示法適合所有同構比較
i = 0; j = 1; i, j一次向後進行比較
環的處理方法:先複製一倍
數論
- 任意n>1,n∈N,n=p1^a1*p2^a2…pn^an
- 例一:質數列表(prime number list)
偉大的Eratosthenes篩法(主動_nlog(logn) )
麻煩的 線性篩法(被動_n):從頭遍歷,篩最小質因子乘積和因子平方
例二:POJ 2689
先篩sqrt(U),再根據sqrt(U)篩較大區間,然後枚舉 - 求最大公約數 一行搞定
return b==0 ? a : gcd(b, a%b);
- 裴蜀定理(Bézout’s identity) 證同 歐幾里得
-POJ 3090 求能看到的點數 - 並不不重要的 排列組合
機械工業出版社 出版 《組合數學》
《算法導論》 - 快速冪 求 a^b 先求一半再平方
避免高精:64位int * 64位int % 64位int(如 2^64) => b個a相加再mod - 矩陣:(單位矩陣, 全零矩陣)
-遞推矩陣(斐波那契數列) - 高斯消元
秩(rank) 行秩 列秩
0 0 0 | 1//無解
0 0 0 | 0//多解 - 求異或和(xor)最大:
異或和:二進制碼和
基本性質AxorA=0,Axor0=A
法1:用trie樹
法2:高斯消元思想
另:既約剩餘系, 費馬小定理, 歐拉函數 , 乘法逆元, 數論倒數 , 中國剩餘定理 , 概率與期望……
擴展歐幾里德算法與數論倒數
搜索
DFS
-全排列
-N皇后
-自然數拆分
-數獨 POJ 2676 3074 3076
BFS
-武士風度的牛
-補丁 VS 錯誤
-POJ 3322
貪心
適用於 組合優化問題
例一:雷達
問題轉化:見下圖
例二:搬書
擺書的方法:豎着擺!!!他就不能好好放書嘛!!!
讀得越早位置越靠上
例三:牛吃花問題(吃得多的送得早,簡稱"作")
我寧可去做牛吃草……
比較TxDy與TyDx的大小判斷xy哪個先被送走
例四:疊奶牛問題
搬書還是更人性……壓在奶牛上的最後一棵花
方法≈例三,判斷兩頭奶牛交換前後風險值變化
下面是一堆雜題
1. 求n個點的無向簡單連通圖的個數(計數問題)
可求補集,即無向簡單不連通圖
f(n) = 2^[m(m-1)/2]-he(i=1…n-1)f(i)2^[(n-i)(n-i-1)/2]C(n-1…i-1)
2. 求無序對數 題略
k=3 時 ans = [nixuduishu(a,b)+ni(a,c)+ni(b,c)]/2
圖論
概念
存儲
鄰接矩陣 dis[i][j]=1
鄰接表 用鏈表
遍歷
深度優先搜索(用棧 遞歸實現)
廣度優先搜索(用隊列)
題
-POJ 1125 (最短路)
-判斷二分圖(染色)
-DAG的拓撲排序(刪除入度爲0的點,鄰接表) //砸攝像頭問題
-POJ 2367
-路徑權值定義爲邊的權值和+點的權值最小值,求最短路
-熱浪
-POJ 3259 判負權環
-POJ 3463 / 3635 / 2200 (次短路)
-POJ 1025 / 2330 (差分約束模型)
-POJ 1734
-POJ 1679 / 1639 (最小生成樹)
-NOIP 2013 貨車運輸 (LCA)
-POJ 2976 Dropping tests(01分數規劃)
朱劉算法 求解最小樹形圖