目录
0.前言
算法这种东西,有时候其实并不管用,还是一波暴力走人,退役。。。。。。干脆。
一.动态规划——必考必考必考!!!
DP这种算法,不是说了概念就能懂得,只有身经百战,然后靠一波运气才行。下面有一些常见的DP考法:
1.背包
这种DP方式很常见,并且范围很广,而且有较明显的方法提示。就是在题目有求和的最大的限制,并且给你一个数列的时候,肯定是背包,说都不用说。还有个更明显的标志:每个数及其和不大!这里有两种常考背包:
(1)01背包
for (int i = 1; i <= n; i ++){//n表示物品种数
for (int j = m; j >= w[i]; j --){//m表示背包容量
dp[j] = max (dp[j], dp[j - w[i]] + v[i]);//w表示每种物品的体积大小,v则表示价值
}
}
for (int i = 1; i <= m; i ++)
ans = max (dp[i], ans);
(2)完全背包
for (int i = 1; i <= n; i ++){//各变量含义同上
for (int j = w[i]; j <= m; j ++){//与01背包反过来
dp[j] = max (dp[j], dp[j - w[i]] + v[i]);
}
}
for (int i = 1; i <= m; i ++)
ans = max (dp[i], ans);
但是不能完全靠这板子去得分,题目经常都很灵活,但是只要稍微改动一下就行了。比如:让背包去存已经用的物品个数,因为题目限制了物品个数。
2.线性DP
这种DP就包括最长公共上升子序列,最长上升(下降)子序列,单调队列,背一下,这种题目挺好做的。
3.多维DP
这是最难想的DP类型的题目,通常在一个矩阵的背景下进行,这种特别难,只有多花时间想一想,有几个经典的类型:
1.最大子矩阵:一行一行的往下转移
2.创意吃鱼法:一层一层的往左和往下扩展
总而言之,从一个下标转移到下一个下标,或从一排转移到下一排的转移方式,是DP的精髓。
DP优化我就不想说了,比如斜率优化、平行四边形优化根本就不是我的料。
二.贪心
贪心和动态规划容易搞混,但是记住,需要状态转移,有多种情况的就是动态规划,所谓多种情况,就是你贪心考虑不到。
贪心的精髓就是贪。所以贪心经常需要排序,这有点玄学,反正我有点懵,凭着感觉去贪就行了。
三.模拟
我认为,这个就不叫算法,其实就考察一个东西:细心
四.图论——很灵活
这个算法不仅内容多,而且考的非常灵活,经常让你手足无措,最后看了题解才发现就一个最小生成树(举个例子)而已。
这里先上模板:
1.最短路
分spfa和Dijkstra(floyd就不说了)
(1)spfa
这个我就不想说了
(2)Dijkstra(+堆优化)时间复杂度远快于spfa
注意,Dijkstra是不能有负环的,是有spfa才能判环(若一个点进入n+1次,就存在环)
2.最小生成树
直接上了:
bool cmp (int x, int y){
return w[x] < w[y];
}
void makeSet (int x){
for (int i = 1; i <= x; i ++)
f