12 2020 档案
摘要:注意是要求最大化高度(运输量),而不是最小化路径长度。 于是二分高度,判断只走高度不超过$mid$的边的情况下,到达终点的最短距离。若不能抵达终点则返回false。 最后输出答案时要先check()出最优解再输出。 const int N=1010; struct Node { int v,h,c;
阅读全文
摘要:$LCS$简单变形 状态表示:\(f(i)\):$1~i$中最长上升子序列的和值。 状态转移: $f(i)=\begin a[1],i = 1\max(f(k)+a[i]),1≤k<i && a[i]>a[k] \end$ const int N=1010; int f[N]; int a[N];
阅读全文
摘要:水题~ const int N=25; char g[N][N]; bool vis[N][N]; int n,m; PII st; bool check(int x,int y) { return x>=0 && x<n && y>=0 && y<m; } int bfs() { queue<PI
阅读全文
摘要:由于边权有$1$和$2$两种情况,所以就不能用裸的$BFS$了,改成优先队列$BFS$(其实就是$dijkstra$)。 const int N=210; struct Node { int dis; int x,y; bool operator>(const Node &W) const { re
阅读全文
摘要:$flood-fill$裸题 \(DFS\) const int N=110; char g[N][N]; bool vis[N][N]; int n,m; bool check(int x,int y) { return x>=0 && x<n && y>=0 && y<m; } void dfs
阅读全文
摘要:简单回溯法 注意:回溯法搜索全空间可不清vis数组 const int N=25; int a[N]; bool vis[N]; int n; bool isprime(int x) { for(int i=2;i*i<=x;i++) if(x % i == 0) return false; ret
阅读全文
摘要:读题$→$$BFS$裸题,信心满满交了一发$→$$\color$ const int N=10; char g[N][N]; int dist[N][N]; int n,m,tim; PII st,ed; bool check(int x,int y) { return x>=0 && x<n &&
阅读全文
摘要:水题~ int cmp(double a,double b) { if(fabs(a-b) < eps) return 0; return a>b?1:-1; } int main() { double x; while(~scanf("%lf",&x)) { if(!cmp(x,0)) break
阅读全文
摘要:一般情况下,动态规划的解题步骤是: 第一步:根据原问题和子问题来确定状态(我的dp数组要表示什么东西) 第二步:根据状态确定状态转移方程(递推式,怎样求解dp数组) 第三步:确定要不要优化和编程实现方式 (其实可以这样理解——第一步是确定“我是谁,我在哪”,第二步是确定“我从哪里来”或者“我到哪里去
阅读全文
摘要:状态表示:\(f(i,j)\):从下标$i$合并到下标$j$的最大价值。 先看石子合并($n$堆石子): $$1,2,...,n$$ $f(1,n)$即为答案。 再看环形: 最后的答案为:$f(1,n)(f(n,1)和f(1,n)结果相同),f(2,1),f(3,2),...,$中的最小值。 我们当
阅读全文
摘要:$0-1$背包裸题 const int N=110,M=1010; int f[M]; int n,m; int main() { cin>>m>>n; for(int i=1;i<=n;i++) { int v,w; cin>>v>>w; for(int j=m;j>=v;j--) f[j]=ma
阅读全文
摘要:$LIS$简单变形。 状态表示: \(l[i]\):$1~i$的最长上升子序列长度 \(r[i]\):$i~n$的最长下降子序列长度 注意最后是输出出列的人数=_=。 const int N=110; int a[N]; int l[N],r[N]; int n; int main() { cin>
阅读全文
摘要:经典的区间$DP$问题。 区间$DP$特征:从小区间逐渐向大区间扩展递推。 题解 贪心只能处理“任取两堆”,而不能处理“相邻两堆”。任取两堆的题目就是合并果子。 状态表示:\(f(i,j)\):合并区间$[i,j]$的最小代价 状态转移:$f(i,j) = \begin0,i = j\ \under
阅读全文
摘要:经典哈夫曼树的模型,每次合并重量最小的两堆果子即可。 const int N=10010; int a[N]; int n; int main() { cin>>n; priority_queue<int,vector<int>,greater<int> > heap; for(int i=1;i<
阅读全文
摘要:新名词$get$:序列自动机 思路挺好想的,一共$n$个位置,对每个位置建立$26$个指针,指向后面第一次出现对应字母的位置。倒序处理一遍即可。 注意: 不存在对应字母的话位置记为$0$ 下标$0$也要初始化 子序列进行匹配时从下标$0$开始匹配,下标$0$存放的指针代表$1~n$中第一次出现对应字
阅读全文
摘要:题意 给定一个字符串 S,求出 S 中所有的既是前缀又是后缀的子串。 题解 求出 next 数组,答案就是 len, next[len], next[next[len]],...直到为0为止。 const int N=4e5+10; char s[N]; int ne[N]; int n; void
阅读全文
摘要:题意 给你一个字符串,让这个字符串变成一个至少有两个循环节的字符串,问至少添加几个字符,添加字符只能在头部和尾部添加不能在中间添加(这是个环)。 裸KMP求最小循环节。 const int N=1e5+10; char s[N]; int ne[N]; int n; void init() { fo
阅读全文
摘要:$spfa$判负环裸题 const int N=510; vector<PII> g[N]; int dist[N]; bool vis[N]; int cnt[N]; int n,m,w; bool spfa() { memset(dist,0x3f,sizeof dist); memset(cn
阅读全文
摘要:KMP简单变形,不能重复用字段,所以要进行一点小修改。 很自然的想到,原本在文本串中找到了模式串之后,单纯ans++,下一次循环必然是j=Next[j],就是j回溯到Next[j]位置;那么,这个时候就相当于用了一些重复字段(Next[j]位置前的那些字符,都是被重复使用了),那么显然,在ans++
阅读全文
摘要:$0-1$背包解法 适用数据范围:\(N≤40,M≤10^6\) 状态表示:\(f(i,j)\):从前$i$个物品中选,花费不超过(小于等于)$j$的方案数。 最后累加$f(n,0~m)$即可。 const int N=45,M=1e6+10; LL price[N]; LL f[M]; LL n,
阅读全文
摘要:折半搜索,$O(n)$型枚举,二分查找相反数个数,时间复杂度(\(O(n^2logn)\)) const int N=4010; int a[N],b[N],c[N],d[N]; int ab[N*N]; int n; int main() { cin>>n; for(int i=0;i<n;i++
阅读全文
摘要:由于可以在任意时刻发送数据包,对于1到n的所有路径,尽管所用时间不同,可你完全可以通过调整他们的开始时间,使他们最后在同一时间到达。 故题目转换为求$1$~$n$的路径数目。规定了图为DAG,拓扑排序即可。 const int N=1e5+10; vector<PII> g[N]; int din[
阅读全文
摘要:分层图最短路,注意按照题意中的“穿过”的定义来模拟。 const int N=1e5+10; struct Node { int dis; int u,cnt; bool operator>(const Node &W) const { return dis>W.dis; } }; vector<P
阅读全文

浙公网安备 33010602011771号