OI算法复习
搜集一些算法,赛前背一背有好处的
转自各大网站
前排感谢:hzwer、风了咕凉
前辈。。。Orz
快速读入:
- int read()
- {
- int x=,f=;char ch=getchar();
- while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
- while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
- return x*f;
- }
经典快排:虽说C++直接sort就好了。。。
- #include <iostream>
- using namespace std;
- void Qsort(int a[], int low, int high)
- {
- if(low >= high)
- return;
- int first = low;
- int last = high;
- int key = a[first];
- while(first < last)
- {
- while(first < last && a[last] >= key)
- --last;
- a[first] = a[last];
- while(first < last && a[first] <= key)
- ++first;
- a[last] = a[first];
- }
- a[first] = key;
- Qsort(a, low, first-);
- Qsort(a, first+, high);
- }
归并排序:
- template <typename T>
- void MergeSort (T data[], int size)
- {
- if ( size> )
- {
- //预处理
- int mid=size/;
- int numOfleft=mid;
- int numOfright=size-mid;
- T* left=new T[numOfleft];
- T* right=new T[numOfright];
- //分
- std::copy(data, data+numOfleft, left);
- std::copy(data+numOfleft, data+size, right);
- MergeSort(left, numOfleft);
- MergeSort(right, numOfright);
- //合
- std::merge(left, left+numOfleft, right, right+numOfright, data);
- //清理
- delete[] left;
- delete[] right;
- }
- }
堆排:
- template <typename T>
- void heap_down (T data[], int i, const int& size)
- {
- int p=i*+;
- while ( p<size )
- {
- if ( p+<size )
- {
- if ( data[p]<data[p+] )
- ++p;
- }
- if ( data[i]<data[p] )
- {
- std::swap(data[p], data[i]);
- i=p;
- p=i*+;
- }
- else
- break;
- }
- }
- template <typename T>
- void HeapSort (T data[], int size)
- {
- int i;
- for (i=(size-)/; i>=; --i)
- heap_down(data, i, size);
- for (i=size-; i>; --i)
- {
- std::swap(data[], data[i]);
- heap_down(data, , i);
- }
- }
拓扑排序:
- #include<iostream>
- #include<cstdio>
- using namespace std;
- struct Edge
- {
- int to,next;
- }E[];
- int head[],r[],s[];
- int node=;
- int n;
- void insert(int u,int v)
- {
- E[++node]=(Edge){v,head[u]};
- head[u]=node;
- r[v]++;
- }
- void topsort()
- {
- int t=,top=;
- for(int i=;i<=n;i++)
- if(!r[i])
- {
- s[++top]=i;
- }
- while(t<=top)
- {
- int x=s[t++];
- for(int i=head[x];i;i=E[i].next)
- {
- r[E[i].to]--;
- if(!r[E[i].to])
- {
- s[++top]=E[i].to;
- }
- }
- }
- }
kahn算法(NOIP2013车站分级为例子)纯过程形式:
- #include<iostream>
- #include<cstring>
- using namespace std;
- const int MAXN=+;
- int n,m,ans=;
- int B[MAXN]={},R[MAXN]={},SK[MAXN]={};//R储存入度 SK储存入度为0的点
- bool A[MAXN]={},F[MAXN]={},E[MAXN][MAXN]={};//F判断点是否已被访问 E判断两点是否存在边
- int main()
- {
- /*cin>>n>>m;
- for(int i=1;i<=m;i++)
- {
- int s;
- memset(A,0,sizeof(A));
- cin>>s;
- for(int j=1;j<=s;j++)
- {
- cin>>B[j];
- A[B[j]]=1;
- }
- for(int j=B[1];j<=B[s];j++)
- if(!A[j])
- for(int k=1;k<=s;k++)
- if(!E[j][B[k]])
- {
- E[j][B[k]]=1;
- R[B[k]]++;
- }
- }*///初始化
- int top;
- while()
- {
- top=;
- for(int i=;i<=n;i++)//遍历n个点
- if(!R[i]&&!F[i])//如果入度为0且没有被访问过,则加入SK数组
- {
- SK[++top]=i;//加入SK数组
- F[i]=;//i点已被访问
- }
- if(top==)break;//如果所有的点都被访问则跳出
- for(int i=;i<=top;i++)
- for(int j=;j<=n;j++)
- if(E[SK[i]][j])//判断是否有边
- {
- E[SK[i]][j]=;//将边移除
- R[j]--;//入度-1
- }
- ans++;
- }
- cout<<ans<<endl;
- return ;
- }
并查集:
- int find(int x)
- {
- while(f[x]!=) x=f[x];
- return x;
- }
快速幂:
- int modexp(int a,int b,int n)
- {
- int ret=;
- int tmp=a;
- while(b)
- {
- if(b&0x1) ret=ret*tmp%n;
- tmp=tmp*tmp%n;
- b>>=;
- }
- return ret;
- }
欧几里得算法:
- int gcd(int a,int b)
- {
- return b?gcd(b,a%b):a;
- }
拓展欧几里德算法:
- int gcd(int a,int b,int &x,int &y){
- if (b==){
- x=,y=;
- return a;
- }
- int q=gcd(b,a%b,y,x);
- y-=a/b*x;
- return q;
- }
spfa:
- struct Edge
- {
- int to,w,next;
- }E[];
- int node=,head[];
- void insert(int u,int v,int w)
- {
- node++;
- E[node]=Edge{v,w,head[u]};
- head[u]=node;
- }
- int spfa(int s,int t)
- {
- int dist[];
- bool vis[];
- memset(dist,0x7f,sizeof(dist));
- memset(vis,,sizeof(vis));
- dist[s]=;vis[s]=;
- queue<int> Q;
- Q.push(s);
- while(!Q.empty())
- {
- int q=Q.front();Q.pop();
- for(int i=head[q];i;i=E[i].next)
- if(dist[E[i].to]>dist[q]+E[i].w)
- {
- dist[E[i].to]=dist[q]+E[i].w;
- if(!vis[E[i].to])
- {
- Q.push(E[i].to);
- vis[E[i].to]=;
- }
- }
- vis[q]=;
- }
- return dist[t];
- }
spfa_dfs判负环:
- #include<iostream>
- #include<cstring>
- using namespace std;
- struct Edge
- {
- int to,w,next;
- }E[];
- int node=,head[],dist[];
- bool vis[];
- int n,m;
- bool flag;
- void insert(int u,int v,int w)
- {
- E[++node]=(Edge){v,w,head[u]};
- head[u]=node;
- }
- void spfa_dfs(int s)
- {
- vis[s]=;
- for(int i=head[s];i;i=E[i].next)
- {
- if(dist[E[i].to]>dist[s]+E[i].w)
- {
- if(vis[E[i].to]){flag=;return;}
- else
- {
- dist[E[i].to]=dist[s]+E[i].w;
- spfa_dfs(E[i].to);
- }
- }
- }
- vis[s]=;
- }
- bool check()
- {
- flag=;
- memset(dist,0x7f,sizeof(dist));
- memset(vis,,sizeof(vis));
- for(int i=;i<=n;i++)
- {
- dist[i]=;
- spfa_dfs(i);
- if(flag) return ;
- }
- return ;
- }
floyd:
- const int maxn=,
- INF=;
- int n,Dist[maxn][maxn],Graph[maxn][maxn];
- int minn=INF;
- void floyd()
- {
- //memcpy(Graph,Dist,sizeof(Dist));
- for(int k=;k<=n;k++)
- {/*拓展求最小环
- for(int i=1;i<k;i++)
- for(int j=i+1;j<k;j++)
- minn=min(minn,Dist[i][j]+Graph[j][k]+Graph[k][i]);*/
- for(int i=;i<=n;i++)
- for(int j=;j<=n;j++)
- {
- int temp=Dist[i][k]+Dist[k][j];
- if(temp<Dist[i][j])
- Dist[i][j]=Dist[j][i]=temp;
- }
- }
- }
Dijkstra:
- #include <iostream>
- #include <cstring>
- using namespace std;
- #define MAXN 10000000
- int n,e;
- int matrix[][];
- int dist[];
- void Dijkstra(int s)
- {
- int u,minn;
- bool vis[];
- memset(vis,,sizeof(vis));
- for(int i=;i<n;i++)
- if(matrix[s][i]>)
- dist[i]=matrix[s][i];
- else dist[i]=MAXN;
- vis[s]=;dist[s]=;
- for(int i=;i<n;i++)
- {
- minn=MAXN;
- for(int j=;j<n;j++)
- if(!vis[j]&&dist[j]<minn)
- {
- u=j;
- minn=dist[j];
- }
- vis[u]=;
- for(int j=;j<n;j++)
- if(!vis[j]&&matrix[u][j]>&&minn+matrix[u][j]<dist[j])
- dist[j]=minn+matrix[u][j];
- }
- }
- int main()
- {
- int v;
- cin>>n;
- cin>>e;
- memset(matrix,,sizeof(matrix));
- for(int i=;i<e;i++)
- {
- int x,y,w;
- cin>>x>>y>>w;
- matrix[x][y]=w;
- }
- Dijkstra();
- cin>>v;
- cout<<dist[v];
- return ;
- }
线段树:详见Codevs1082线段树练习3
- #include<iostream>
- #include<cstdio>
- #include<cstring>
- using namespace std;
- struct node
- {
- int left,right,flag;
- long long sum;
- }tree[];
- int n,q;
- int a[];
- void build(int node,int left,int right)
- {
- tree[node].left=left;tree[node].right=right;
- if(left==right)
- {
- tree[node].sum=a[left];
- return;
- }
- int mid=(left+right)>>;
- build(node<<,left,mid);
- build(node<<|,mid+,right);
- tree[node].sum=tree[node<<].sum+tree[node<<|].sum;
- }
- void pushdown(int node)
- {
- int x=tree[node].right-tree[node].left+;
- tree[node<<].flag+=tree[node].flag;
- tree[node<<|].flag+=tree[node].flag;
- tree[node<<].sum+=(x-(x>>))*tree[node].flag;
- tree[node<<|].sum+=(x>>)*tree[node].flag;
- tree[node].flag=;
- }
- void update(int node,int left,int right,int x)
- {
- int mid=(tree[node].left+tree[node].right)>>;
- tree[node].sum+=(right-left+)*x;
- if(tree[node].left==left&&tree[node].right==right)
- {
- tree[node].flag+=x;
- return;
- }
- if(tree[node].left==tree[node].right) return;
- if(tree[node].flag>) pushdown(node);
- if(right<=mid) update(node<<,left,right,x);
- else if(left>mid) update(node<<|,left,right,x);
- else
- {
- update(node<<,left,mid,x);
- update(node<<|,mid+,right,x);
- }
- tree[node].sum=tree[node<<].sum+tree[node<<|].sum;
- }
- long long query(int node,int left,int right)
- {
- int mid=(tree[node].left+tree[node].right)>>;
- if(tree[node].left==left&&tree[node].right==right)
- return tree[node].sum;
- if(tree[node].flag>) pushdown(node);
- if(right<=mid)
- return query(node<<,left,right);
- else if(left>mid)
- return query(node<<|,left,right);
- else
- return query(node<<,left,mid)+query(node<<|,mid+,right);
- }
树状数组:
详见
- #include<iostream>
- #include<cstdio>
- #include<algorithm>
- using namespace std;
- int n,m;
- int f[];
- int lowbit(int x)
- {
- return x&(-x);
- }
- void update(int x,int num)
- {
- while(x<=n)
- {
- f[x]+=num;
- x+=lowbit(x);
- }
- }
- int sum(int x)
- {
- int sum=;
- while(x>)
- {
- sum+=f[x];
- x-=lowbit(x);
- }
- return sum;
- }
- int main()
- {
- n=read();
- for(int i=;i<=n;i++)
- update(i,read());
- m=read();
- for(int i=;i<=m;i++)
- {
- int a=read(),x=read(),y=read();
- if(a==)update(x,y);
- if(a==)printf("%d\n",sum(y)-sum(x-));
- }
- return ;
- }
分块法:
- #include<iostream>
- #include<cstdio>
- #include<cmath>
- #include<algorithm>
- using namespace std;
- int n,m,q,block;
- int a[],b[],pos[],add[];
- void reset(int x)
- {
- int l=(x-)*block+,r=min(x*block,n);
- for(int i=l;i<=r;i++)
- b[i]=a[i];
- sort(b+l,b+r+);//对单个块内进行排序
- }
- int find(int x,int z)//单个块内二分查找
- {
- int l=(x-)*block+,r=min(x*block,n);
- int last=r;
- while(l<=r)
- {
- int mid=(l+r)>>;
- if(b[mid]<z) l=mid+;
- else r=mid-;
- }
- return last-l+;
- }
- void update(int x,int y,int z)
- {
- if(pos[x]==pos[y])//同个块则暴力修改
- for(int i=x;i<=y;i++) a[i]=a[i]+z;
- else//不同块修改左右两边的块
- {
- for(int i=x;i<=pos[x]*block;i++) a[i]=a[i]+z;
- for(int i=(pos[y]-)*block+;i<=y;i++) a[i]=a[i]+z;
- }
- reset(pos[x]);reset(pos[y]);
- for(int i=pos[x]+;i<pos[y];i++)//其余块用add标记,表示增加了z
- add[i]+=z;
- }
- int query(int x,int y,int z)
- {
- int sum=;
- if(pos[x]==pos[y])//单个块暴力查找
- {
- for(int i=x;i<=y;i++)
- if(a[i]+add[pos[i]]>=z) sum++;
- }
- else//多个块左右两边的块暴力查找
- {
- for(int i=x;i<=pos[x]*block;i++)
- if(a[i]+add[pos[i]]>=z) sum++;
- for(int i=(pos[y]-)*block+;i<=y;i++)
- if(a[i]+add[pos[i]]>=z) sum++;
- }
- for(int i=pos[x]+;i<pos[y];i++)//其余块每个二分查找
- sum+=find(i,z-add[i]);
- return sum;
- }
- int main()
- {
- scanf("%d %d",&n,&q);
- block=(int)sqrt(n);//每个块的大小
- for(int i=;i<=n;i++)
- {
- scanf("%d",&a[i]);
- pos[i]=(i-)/block+;
- b[i]=a[i];
- }
- if(n%block) m=n/block+;//计算块的个数,如有多余则+1
- else m=n/block;
- for(int i=;i<=m;i++) reset(i);//对每个块进行块内排序
- for(int i=;i<=q;i++)
- {
- char ch;int x,y,z;
- scanf("\n%c %d %d %d",&ch,&x,&y,&z);
- if(ch=='M') update(x,y,z);
- else printf("%d\n",query(x,y,z));
- }
- return ;
- }
倍增算法:
RMQ:这里借鉴了一下黄学长的模板。。。Orz膜拜前辈
- #include<iostream>
- #include<cmath>
- #include<iostream>
- using namespace std;
- int A[];
- int MX[][];
- int n,q;
- void RMP_INIT()
- {
- for(int i=;i<=n;i++)
- MX[i][]=A[i];
- int m=log(n)/log();
- for(int i=;i<=m;i++)
- for(int j=n;j>;j--)
- {
- MX[j][i]=MX[j][i-];
- if(j+(<<(i-))<=n)MX[j][i]=max(MX[j][i],MX[j+(<<(i-))][i-]);
- }
- }
- int RMP(int l,int r)
- {
- int m=log(r-l+)/log();
- return max(MX[l][m],MX[r-(<<m)+][m]);
- }
KMP算法:
- #include<iostream>
- #include<cstring>
- using namespace std;
- char S[],T[];
- int ls,lt;
- int next[];
- void initnext(char *t,int *next)
- {
- int j=;
- int len=strlen(t);
- memset(next,,sizeof(next));
- for(int i=;i<len;i++)
- {
- while(j&&t[i]!=t[j]) j=next[j];
- if(t[i]==t[j]) j++;
- next[i+]=j;
- }
- }
- int KMP(char *s,char *t)
- {
- int j=,ans=;
- int ls=strlen(s),lt=strlen(t);
- for(int i=;i<ls;i++)
- {
- while(j&&s[i]!=t[j]) j=next[j];
- if(s[i]==t[j]) j++;
- if(j==lt)
- {
- ans++;
- j=next[j];
- }
- }
- return ans;
- }
高斯消元:感谢浙大学长。。。Orz
- #include<iostream>
- #include<cmath>
- using namespace std;
- #define eps 1e-9
- const int MAXN=;
- double a[MAXN][MAXN],x[MAXN]; //方程的左边的矩阵和等式右边的值,求解之后 x存的就是结果
- int equ,var;//方程数和未知数个数
- /* *返回0表示无解,1表示有解*/
- int Gauss()
- {
- int i,j,k,col,max_r;
- for(k=,col=;k<equ&&col<var;k++,col++)
- {
- max_r=k;
- for(i=k+;i<equ;i++)
- if(fabs(a[i][col])>fabs(a[max_r][col])) max_r=i;
- if(fabs(a[max_r][col])<eps) return ;
- if(k!=max_r)
- {
- for(j=col;j<var;j++) swap(a[k][j],a[max_r][j]);
- swap(x[k],x[max_r]);
- }
- x[k]/=a[k][col];
- for(j=col+;j<var;j++) a[k][j]/=a[k][col];
- a[k][col]=;
- for(i=;i<equ;i++)
- if(i!=k)
- {
- x[i]-=x[k]*a[i][k];
- for(j=col+;j<var;j++) a[i][j]-=a[k][j]*a[i][col];
- a[i][col]=;
- }
- }
- return ;
- }
分解质因数:感谢浙大学长。。。Orz
- long long fac[],fac_num;
- void getfactor(int num)
- {
- fac_num=;
- for(int i=;i*i<=num;i++)
- {
- if(num%i==)
- {
- fac[fac_num++]=i;
- while(num%i==) num/=i;
- }
- }
- if(num>) fac[fac_num++]=num;
- }
欧拉函数:
- /*1.欧拉函数是积性函数,但不是完全积性函数,即φ(mn)=φ(n)*φ(m)只在(n,m)=1时成立.
- 2.对于一个正整数N的素数幂分解N=P1^q1*P2^q2*...*Pn^qn.
- φ(N)=N*(1-1/P1)*(1-1/P2)*...*(1-1/Pn).
- 3.除了N=2,φ(N)都是偶数.
- 4.设N为正整数,∑φ(d)=N (d|N). 求小于等于N的与N互质的数的和 :ans=N*phi(N)/2;*/
- /* 欧拉phi(x)函数等于不超过x且和x互素的整数个数。 */
- #include<iostream>
- #include<cstring>
- #include<algorithm>
- using namespace std;
- const int MAXN=;
- int phi[MAXN]; /* 单个欧拉函数值*/
- int euler_phi(int n)
- {
- int m=sqrt(n+0.5),ans=n;
- for(int i=;i<=m;i++)
- {
- if(n%i==) ans=ans/i*(i-);
- while(n%i==)n/=i;
- }
- if(n>) ans=ans/n*(n-);
- return ans;
- }
- /*欧拉函数 表*/
- void phi_table(int n)
- {
- memset(phi,,sizeof(phi));
- phi[]=;
- for(int i=;i<=n;i++)
- if(!phi[i])
- for(int j=i;j<=n;j+=i)
- {
- if(!phi[j])phi[j]=j;
- phi[j]=phi[j]/i*(i-);
- }
- }
埃氏筛法:O(nlog(logn))
- #include<iostream>
- #include<cstring>
- using namespace std;
- const int MAXN=;
- int isprime[MAXN];
- void getprime(int n)
- {
- memset(isprime,,sizeof(isprime));
- isprime[]=isprime[]=;
- for(int i=;i*i<n;i++)
- if(isprime[i])
- for(int j=i*i;j<=n;j+=i)
- isprime[j]=;
- }
欧拉筛法:
- const int MAXN=;
- int cnt=;
- int prime[MAXN];
- bool mark[MAXN];
- void Prime(int x)
- {
- for(int i=;i<=x;i++)
- {
- if(!mark[i]) prime[++cnt]=i;
- for(int j=;j<=cnt&&prime[j]*i<=x;j++)
- {
- mark[prime[j]*i]=;
- if(i%prime[j]==) break;
- }
- }
- }
后缀数组:
- #include<iostream>
- #include<cstring>
- using namespace std;
- const int MAXN=+;
- int WA[MAXN],WB[MAXN],WV[MAXN],WS[MAXN];
- int Rank[MAXN],Height[MAXN];
- int cmp(int *r , int a, int b, int l)
- {
- return r[a] == r[b] && r[a+l] == r[b+l];
- }
- void DA(char *r , int *sa , int n, int m)
- {
- int i, j, p, *x = WA, *y = WB;
- for(i = ; i < m; i++) WS[i] = ;
- for(i = ; i < n; i++) WS[x[i] = r[i]]++;
- for(i = ; i < m; i++) WS[i] += WS[i-];
- for(i = n-; i >= ; i--) sa[--WS[x[i]]] = i;
- for(j = ,p = ; p < n ; j <<= ,m = p)
- {
- for(p = , i = n - j; i < n; i++) y[p++]=i;
- for(i = ; i < n; i++)
- if(sa[i] >= j)
- y[p++] = sa[i] - j;
- for(i = ; i < n; i++) WV[i] = x[y[i]];
- for(i = ; i < m; i++) WS[i] = ;
- for(i = ; i < n; i++) WS[WV[i]]++;
- for(i = ; i < m; i++) WS[i] += WS[i-];
- for(i = n-; i >= ; i--) sa[--WS[WV[i]]] = y[i];
- for(swap(x,y),p = ,x[sa[]] = ,i = ; i < n;i++)
- x[sa[i]]=cmp(y,sa[i-],sa[i],j)?p-:p++;
- }
- }
- void calheight(char *r,int *sa,int n)
- {
- int i,j,k=;
- for(i=;i<=n;i++)Rank[sa[i]]=i;
- for(i=;i<n;Height[Rank[i++]]=k)
- for(k?k--:,j=sa[Rank[i]-];r[i+k]==r[j+k];k++);
- return;
- }
- char str[MAXN];
- int sa[MAXN];
- int main()
- {
- cin>>str;
- int n=strlen(str);
- str[n]=;
- DA(str,sa,n+,);
- calheight(str,sa,n);
- return ;
- }
最大子串:
- int maxSubstr() {
- int sum = , answer = -INF;
- for (int i = ; i <= n; i++) {
- sum += a[i];
- answer = max(answer, sum);
- sum = max(sum,);
- }
- return answer;
- }
SG函数:(转自SimonS大佬征战亚洲赛时用的模板
- #define MAX 1005
- /* 计算从1-n范围内的SG值。
- Array(存储可以走的步数,Array[0]表示可以有多少种走法)
- Array[]需要从小到大排序 */
- /*HDU1847博弈SG函数
- 1.可选步数为1-m的连续整数,直接取模即可,SG(x) = x % (m+1);
- 2.可选步数为任意步,SG(x) = x;
- 3.可选步数为一系列不连续的数,用GetSG(计算) */
- int SG[MAX], hash[MAX];
- void GetSG(int Array[], int n = MAX-)
- {
- memset(SG, , sizeof(SG));
- for(int i = ; i <= n; ++i)
- {
- memset(hash, , sizeof(hash));
- for(int j = ; j <= Array[]; ++j)
- {
- if(i < Array[j]) break;
- hash[SG[i - Array[j]]] = ;
- }
- for(int j = ; j <= n; ++j)
- if(!hash[j]){ SG[i] = j;break; }
- }
- }
先占坑,慢慢填
OI算法复习的更多相关文章
- OI算法复习汇总
各大排序 图论: spfa floyd dijkstra *拉普拉斯矩阵 hash表 拓扑排序 哈夫曼算法 匈牙利算法 分块法 二分法 费马小定理: a^(p-1) ≡1(mod p) 网络流 二分图 ...
- C#冒泡算法复习
C#冒泡算法复习 冒泡算法的意思:每一趟找到一个最小或最大的数放到最后面,比较总数的n-1次(因为比较是2个双双比较的) 第一层循环表示进行比较的次数,总共要比较(数的)-1次 (因为比较是2个双双比 ...
- C语言排序算法复习
排序算法有很多种,这里在复习和分析的基础上,做一个自己的总结: 首先要知道有哪些排序算法,google一下,有云C语言7大经典排序算法(也有8大).主要包括冒泡排序,快速排序,选择排序,插入排序,希尔 ...
- KMP算法复习【+继续学习】
离NOIP还剩12天,本蒟蒻开始准备复习了. 先来个KMP[似乎我并没有写过KMP的blog] KMP KMP算法是解决字符串匹配问题的一个算法,主要是单对单的字符串匹配加速,时间复杂度O(m + n ...
- 算法复习周------“动态规划之‘最长公共子序列’”&&《计蒜课》---最长公共子串题解
问题描述: 这个问题其实很容易理解.就是给你两个序列X={x1,x2,x3......xm} Y={y1,y2,y3......ym},要求找出X和Y的一个最长的公共子序列. 例:Xi={A, B, ...
- K-Means聚类和EM算法复习总结
摘要: 1.算法概述 2.算法推导 3.算法特性及优缺点 4.注意事项 5.实现和具体例子 6.适用场合 内容: 1.算法概述 k-means算法是一种得到最广泛使用的聚类算法. 它是将各个聚类子集内 ...
- 通过“回文字算法”复习C++语言。
一.什么是回文字 给定一个字符串,从前往后读和从后往前读,字符串序列不变.例如,河北省农村信用社的客服电话是“96369”,无论从后往前读,还是从前后往后读,各个字符出现的位置不变. 二.功能实现 ( ...
- 【转】常用算法复习及实现(C++版)
一.霍夫曼树实现 给定n个权值作为n个叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman tree).哈夫曼树是带权路径长度最短的树,权值较大 ...
- 算法复习——1D/1Ddp优化
搬讲义~~~~ 题目1:玩具装箱(bzoj1010) Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一 ...
随机推荐
- 爬虫之scapy
一 介绍 Scrapy一个开源和协作的框架,其最初是为了页面抓取 (更确切来说, 网络抓取 )所设计的,使用它可以以快速.简单.可扩展的方式从网站中提取所需的数据.但目前Scrapy的用途十分广泛,可 ...
- 洛谷P4822 冻结
题目描述 "我要成为魔法少女!" "那么,以灵魂为代价,你希望得到什么?" "我要将有关魔法和奇迹的一切,封印于卡片之中„„" 在这个愿望被 ...
- 线程组之间的JMeter传递变量
在这个JMeter教程中,我们将了解如何在线程组之间共享和传递变量. 在开发高级JMeter脚本时,很可能您将拥有多个线程组.每个线程组将执行不同的请求. 一个很好的例子就是我们需要使用Bearer ...
- puthon-进程间通信-队列和管道
********进程间通信-队列和管道******** ****进程间通信-队列和管道 IPC(Inter-Process Communication) ****队列 **概念介绍 创建贡献的进程队列 ...
- BZOJ 1977: [BeiJing2010组队]次小生成树 Tree 倍增 最小生成树
好吧我太菜了又调了一晚上...QAQ 先跑出最小生成树,标记树边,再用树上倍增的思路,预处理出: f[u][i] :距离u为2^i的祖先 h[u][i][0/1] :距u点在2^i范围内的最长边和次长 ...
- Codeforces 185B(数学结论)
要点 有不等式\(x^ay^bz^c=a^ab^bc^c(\frac{x}{a})^a(\frac{y}{b})^b(\frac{z}{c})^c<=a^ab^bc^c(\frac{x+y+z} ...
- Django - CRM项目(3)
一.CRM项目的业务逻辑与表结构梳理 1.分析业务逻辑 (1) 引流(sem) (2) 网络咨询师(客服):添加客户信息和查看客户,分配销售 (3) 销售:查看私户 添加跟进记录 失败:加入公户 成功 ...
- Spring注入bean和aop的注意事项
spring注入类没有构造函数,注入成功抽象类,注入失败不写bean注入的名字,默认是bean第一个字母小写的名字,但是bean名字开头是两个大写,则默认是bean的名字前面所有大写都变小写@Auto ...
- net core (上)
net core (上) 本文是基于Windows10的. 下载地址: https://code.visualstudio.com/ insider 版下载地址: https://code.visua ...
- linux替换文件中的某个字符串的命令sed
sed -i 's/java-7-oracle/java-8-oracle/g' /etc/init.d/tomcat7 上面的命令是将tomcat7中的java-7-oracle替换为java-8- ...