2024.7.1杂谈(数位dp,状压,匈牙利,网络流)
数位dp
通常是“统计
eg.板子数字计数
问题特点:
- 目的是计数
- 限制与数位相关
- 用区间限制
- 上界较大(如
)
统计答案可以记搜,也可以用数组递推,从高到低每一位考虑可以填的数字统计答案。
状压
一些状态具有非
状压可以拿来dp,也可以用于更简单地枚举状态。
匈牙利算法
用于解决二分图最大匹配问题。
每次从左部点dfs到右部点:
(1)若右部点没有被匹配,用左部点和它匹配并返回匹配成功。
(2) 若右部点已被匹配,dfs它的匹配点(相当于看能否让它的匹配点换一个右部点匹配),若得到匹配成功的信息,让右部点和当前左部点匹配。
整个过程相当于找一条从左部点以及一条非匹配边开始的增广路。由于非匹配边和匹配边交错出现,每条增广路会让匹配数加一。
bool dfs(int u){
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].v;
if(vis[v]) continue;
vis[v]=true;
if(!mat[v]||dfs(mat[v])){
mat[v]=u;
return true;
}
}
return false;
}
网络流(最大流)
一般用 除了加强版板子。理论上
bool bfs(){
memset(dep,0,sizeof dep);
memcpy(cur,head,sizeof head);
dep[s]=1;
queue<int> q;
q.push(s);
while(!q.empty()){
int u=q.front();
q.pop();
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].v;
if(!dep[v]&&e[i].f){
dep[v]=dep[u]+1;
if(v==t) return true;
q.push(v);
}
}
}
return dep[t];
}
int dfs(int u,int flow){
if(u==t) return flow;
int used=0;
for(int &i=cur[u];i;i=e[i].nxt){
int v=e[i].v;
if(dep[v]==dep[u]+1&&e[i].f){
int rf=dfs(v,min(flow-used,e[i].f));
used+=rf;
e[i].f-=rf;
e[i^1].f+=rf;
if(used==flow) return used;
}
}
return used;
}
void dinic(){
while(bfs()) ans+=dfs(s,0x7fffffff);
}
bfs将图分层,保证增广轮数。
其他东西感性理解一下吧
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】