今天主要學習了線性dp和揹包問題以及快速冪。
1.整數快速冪:
這個直接粘上**
int qpow(int x,int n)
res = res*res;
n = n>>1;
}return ans;
}
2.矩陣快速冪:
主要就是將整數快速冪的乘法運算換做矩陣的乘法
下面的**是方陣的快速冪
const int n=10;
int tmp[n][n];
void multi(int a[n],int b[n],int n)//n為方陣的大小
}
矩陣快速冪的乙個重要應用就是求遞推式,這個在這裡不做延伸。
3.線性dp
最長不下降子串行的長度:
用dp[i]表示前i個元素的lis
對於第i個元素,其所對應的長度應從前往後找,找到所有可以新增的子串行,並取其中的最大值,可知狀態轉移方程:
dp[i]=max(dp[i],dp[j]+1); // j:由1到i
最大連續子段和:
用dp[i]表示以第i個元素為結尾的最大連續子段和
對於第i個元素,其dp[i-1] 已經最優,那麼這個元素要麼加上前面的最優,要麼本身就是最優,可知狀態轉移方程:
dp[i]=max(a[i],dp[i-1]+a[i]);// 然後再遍歷求出最大值即可
最長公共子串行:
假設兩個子串行x[1~m],y[1~n] 且z[1~k]為它們的最長公共子串行,則有:
如果xm=yn,則zk=am=bn(只有這樣子序列才最長),且z[1~k-1]是x[1~m-1]和y[1~n-1]的乙個最長公共子串行;
如果xm!=yn,若zk!=xm,則z[1~k]是x[1~m-1]和y[1~n]的乙個最長公共子串行;若zk!=bn,則z[1~k]是x[1~m]和y[1~n-1]的乙個最長公共子串行。可知狀態轉移方程:
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
if(a[i]==b[j])
4.一些思想
1)先看這樣一道題:
假設我們有乙個序列s,我可以從中取出若干的數,並且這些序列還滿足下面的條件:
1.取出負數的話,我不得錢
2.取出s[i]>=10000的數,我可以得到5塊錢,並且我要把他變成 s[i] = s[i] – 10000
3.其餘情況我只能得到一塊錢
4.取出的數不能打亂原有的順序
問我能不能選出這樣乙個子串行t,使得t中的元素都是不下降的,並且得到錢最多?
這是乙個最長不下降子串行問題,對於大於一萬的數怎麼處理呢?
關鍵來了,可以將大於一萬的數減去一萬,然後將該數變為五個插入到當前數所在位置(這樣處理,每個數的價值就是一,這個數只要選乙個就可以選五個,價值就是五)
2)二維字首和:
採用二階矩陣來記錄矩陣某一點(m,n)和(0,0)所在行列所圍成的矩陣中所有數的和,掃一遍即可求出這個二階矩陣。
ACM暑期集訓4
今天主要學習了線段樹,樹狀陣列,st表,差分,分塊和樹剖 好吧,這個已經沒聽懂了 1.線段樹 線段樹涉及許多應用和思想,以下是今天所學 線段樹主要用於處理一段連續區間的插入,查詢,統計,查詢等操作。複雜度 設區間長度是n,所有操作的複雜度是logn級別。性質 線段樹是平衡的2叉樹,最大深度logn ...
ACM暑期集訓5
今天主要學習力圖論基礎和最短路徑 1.圖論基礎 1 鄰接矩陣存圖 w i j 表示以ij為頂點的邊的權值 const int n 105,inf 9999999 int dis n w n n vis n n,m 鄰接矩陣存圖 for int i 1 i n i for int i 0 i2 鄰接表...
ACM暑期集訓12
今天學了字尾陣列,感覺好難理解,只能搬ppt,粘模板了 1 字尾 suffix i 為從下標i開始的字尾 string abcdef suffix 1 bcdef suffix 2 cdef 什麼是字尾陣列?把乙個字串的所有字尾按字典序進行排序。字尾陣列sa i 表示排名為i的字尾下標是什麼,rk ...