陆续更新----还在专题复习中 没到算法笔记 到时会有更多的干货哦,比如可能会出现的树图(Floyd,SPFA,平衡二叉树的左旋右旋等等)
2022年居然没考 哈哈哈哈哈哈
目录
数学
动态规划
推荐几个刷题网站
数学
这个方法是在PAT的《算法笔记》里面学到的 开始的时候vis数组全部为false(默认bool数组都是fasle) 只要是质数的倍数 那就一定不是质数 则可以全部转为true
同时ans 还可以记录2到n的质数个数
for(int i=2;i
//求得一个数的所有约数
for(int i=1;i<=sqrt(n);i++){
if(n%i==0){
nums.push_back(i);
if(i*i!=n)nums.push_back(n/i);
}
}
int gcd(int a,int b)//求a,b最大公约数
{
if(b==0)return a;
return gcd(b,a%b);
}
int f(int y)//判断闰年
{
if(y%4==0&&y%100!=0||y%400==0) return 1;
return 0;
}
求俩矩形覆盖面积
int overlapWidth = min(ax2, bx2) - max(ax1, bx1);
int overlapHeight = min(ay2, by2) - max(ay1, by1);
int overlapArea = max(overlapWidth, 0) * max(overlapHeight, 0);
原题链接223. 矩形面积 - 力扣(LeetCode) (leetcode-cn.com)
验证2的幂:(n & (n-1)) == 0
验证4的幂:(n & (n-1)) == 0&& (n % 3 == 1)
//哈希 解决循环数
unordered_map map;
int index=0;
while(n!=1&&!map.count(n)){
map[n]=index++;
n=f(n);
}
//快速幂
const int MOD = 1337
int pow(int x, int n) {
int res = 1;
while (n) {
if (n % 2) {
res = (long) res * x % MOD;
}
x = (long) x * x % MOD;
n /= 2;
}
return res;
}
//分数到小数
也是类似于字符串
int num=numerator;//分子
int den=denominator;//分母
string ans="";
if(num*den<0)ans+="-";//如果分子分母相乘为负 前面加一个‘-’号
num=abs(num);//分子取绝对值
den=abs(den);//分母取绝对值
ans+=to_string(num/den);//将俩位相除的值放到字符串里面去
int n =num%den;//如果俩数取余为0 则没有小数
if(n==0){
return ans;
}
如果有小数 或者有无限循环小数 就要具体分析了
详细小伙伴们可以做下leetcode的这题练练手
https://leetcode-cn.com/problems/fraction-to-recurring-decimal/
动态规划
推荐先看看dd大牛的背包九讲https://blog.csdn.net/qq_56263094/article/details/123472877
- 然后看看y大佬的背包九讲基本就能懂了
- https://space.bilibili.com/7836741/channel/seriesdetail?sid=369277
- 刷题可以按这上面的顺序刷题
- https://zhuanlan.zhihu.com/p/126546914
//常见动态转移方程
最大连续子序列和:
dp[i]=m a x ( A[i] , dp[i-1]+A[i])
最长不下降子序列
dp[i] = m a x (dp[i] , dp[j]+1)
三角形最小路径和:
dp[i][j]=min(dp[i+1][j],dp[i+1][j+1])+f[i][j];
//较为复杂的动态转移方程
//最长公共子序列(LCS)
dp[i][j]表示字符串A的i号位和字符串B的j号位之前的LCS长度
边界:dp[i][0] = dp[0][j]=0(0<=i<=n,0<=j<=m)
这样状态dp[i][j]只与其之前的状态有关,由边界出发就可以得到整个dp数组,最后dp[n][m]就是答案
//状态转移方程:
for(int i=1;i<=lenA;i++)
for(int j=1;j<=lenB;j++)
if(A[i]==B[j]){
dp[i][j]=dp[i-1][j-1] + 1;
}else{
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
}
最长回文子串练习https://leetcode-cn.com/problems/longest-palindromic-substring/
//最长回文子串
dp[i][j] 表示S[i]到S[j] 是否是回文子串
边界:dp[i][i]=1,dp[i][i+1] = (S[i] == s[i+1])?1:0
//初始化
for(int i=0; i=j&&s[i]==s[j]) {
dp[i][j]=1;
}
if(s[i]==s[j]&&dp[i+1][j-1]==1) {
dp[i][j]=1;
}
if (dp[i][j] && j - i + 1 > maxLen) {
maxLen = j - i + 1 ;
begin = i;
}
}
}
01背包动态转移方程:https://www.acwing.com/problem/content/2/
//物品只能选一件
//i表示前i个物品 j表示容量 j<=m
二维:f[i][j]=max(f[i-1][j],f[i-1][j-v[i]]+w[i](从小到大枚举)
一维:f[v]=max(f[v],f[j-v]+w[i])(从大到小枚举)
//n是物品个数,m是最大容量
for(int i=1;i<=n;i++){
int v,w;
cin>>v>>w;
for(int j=m;j>=v;j--){
dp[j]=max(dp[j],dp[j-v]+w);
}
}
完全背包动态转移方程:https://www.acwing.com/problem/content/3/
//状态转移方程---物品可以选无限件
f[j]=max{f[j],f[j-v[i]]+w[i]}
//实例 v表示物品体积 w表示物品价值
for(int i=0;i>v>>w;
for(int j=v;j<=m;j++)//(从小到大)
dp[j]=max(dp[j],dp[j-v]+w);
}
多重背包问题一:
跟一维的01背包类似https://www.acwing.com/problem/content/4/
//含义是物品最多可以选k件
for(int i=0;i>v>>w>>s;
for(int j=m;j>=v;j--)
for(int k=1;k<=s&&k*v<=j;k++)
dp[j]=max(dp[j],dp[j-k*v]+k*w);
}
多重背包问题二(当数据量比较大的时候):https://www.acwing.com/problem/content/5/
二进制优化 将多重背包转化为01背包问题
for(int k = 1;k <= s;k *=2){
s -=k;
goods.push_back({v * k,w * k});
}
if(s > 0) goods.push_back({v * s,w * s});
for(auto good : goods) {
for(int j = m; j >= good.v; j --) {
dp[j] = max(dp[j],dp[j - good.v] + good.w);
}
}
二维背包问题https://www.acwing.com/problem/content/8/
#include
using namespace std;
const int maxn = 1010;
int n,v,m;
int dp[maxn][maxn];
int main(){
cin>>n>>v>>m;
for(int i=0;i>a>>b>>c;
for(int j=v;j>=a;j--){
for(int k=m;k>=b;k--)
dp[j][k]=max(dp[j][k],dp[j-a][k-b]+c);
}
}
cout<
背包问题求方案数https://www.acwing.com/problem/content/11/
#include
#include
using namespace std;
const int N = 1010, mod = 1000000007;
int n, m;
int f[N], g[N];
int v[N], w[N];
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i ++ ) cin >> v[i] >> w[i];
for (int i = 0; i <= m; i ++ ) g[i] = 1;
for (int i = 1; i <= n; i ++ )
for (int j = m; j >= v[i]; j -- )
{
int left = f[j], right = f[j - v[i]] + w[i];
f[j] = max(left, right);
if (left > right) g[j] = g[j];
else if (left < right) g[j] = g[j - v[i]];
else g[j] = g[j] + g[j - v[i]];
g[j] %= mod;
}
cout << g[m] << endl;
return 0;
}
以上背包问题的解决方法都出自y大佬的视频和acwing题库
还有混合背包问题 二维费用背包问题 背包问题具体方案等等 要的小伙伴自取
推荐几个刷题网站
leetcode 上面也很多出的好的题 可以分专题刷 网站都分类好了的
蓝桥云课 这里面有蓝桥杯的真题 我觉得比那个蓝桥杯官方的oj好用的多
蓝桥杯VIP题 这里面没有蓝桥杯的VIP题 这里面没有蓝桥杯的VIP题 这里面没有蓝桥杯的VIP题 重要的事情说三遍
AcWing NOI金牌北京大学y大佬一个人做的 常常有比赛 出的题都挺有意思的 里面涵盖了所有背包问题 推荐