voidselect_sort(int*a,int n){for(int i =0; i < n; i++){int t = i;for(int j = i +1; j < n; j++){if(a[j]< a[t]) t = j;}if(i != t)swap(a[t], a[i]);}}
插入排序
voidinsert_sort(int*a,int n){for(int i =1; i < n; i++){int t = a[i];int j = i;while(j >0&& t < a[j -1]){
a[j]= a[j -1];
j--;}
a[j]= t;}}
归并排序
voidmerge_sort(int*a,int l,int r){if(r - l <=1){if(r - l ==1&& a[r]< a[l]){swap(a[r], a[l]);}return;}int mid =(l + r)>>1;merge_sort(a, l, mid);merge_sort(a, mid +1, r);int*temp =(int*)malloc(sizeof(int)*(r - l +1));int p1 = l, p2 = mid +1, k =0;while(p1 <= mid || p2 <= r){if(p2 > r || p1 <= mid && a[p1]< a[p2]){
temp[k++]= a[p1++];}else{
temp[k++]= a[p2++];}}memcpy(a + l, temp,sizeof(int)*(r - l +1));free(temp);}
逆序对
#defineswap(a, b){\a ^= b, b ^= a, a ^= b;\}voidmerge_sort(int*arr,int l,int r){if(r - l <=1){if(r - l ==1&& arr[r]< arr[l]){swap(arr[l], arr[r]);
cnt++;}return;}int mid =(l + r)>>1;merge_sort(arr, l, mid);merge_sort(arr, mid +1, r);int*temp =(int*)malloc(sizeof(int)*(r - l)+1);int p1 = l, p2 = mid +1, k =0;while(p1 <= mid || p2 <= r){if(p2 > r || p1 <= mid && arr[p1]<= arr[p2]){
temp[k++]= arr[p1++];}else{
temp[k++]= arr[p2++];
cnt += mid - p1 +1;}}memcpy(arr + l, temp,sizeof(int)*(r - l +1));free(temp);}
快速排序
voidquick_sort(int*q,int l,int r){if(l >= r)return;int i = l -1, j = r +1, x = q[(l + r +1)>>1];while(i < j){do i++;while(q[i]< x);do j--;while(q[j]> x);if(i < j)swap(q[i], q[j]);}quick_sort(q, l, i -1),quick_sort(q, i, r);}
快速排序求第k大值
intquick_sort(int q[],int l,int r,int k){if(l >= r)return q[l];int i = l -1, j = r +1, x = q[l + r >>1];while(i < j){do i ++;while(q[i]< x);do j --;while(q[j]> x);if(i < j)swap(q[i], q[j]);}if(j - l +1>= k)returnquick_sort(q, l, j, k);elsereturnquick_sort(q, j +1, r, k -(j - l +1));}
最大子数组
#include<iostream>usingnamespace std;constint N =100;int a[N], dp[N], rec[N];int n;// 1 -2 4 5 -2 8 3 -2 6 3 7 -1 (12)// dp[i];以a[i]结尾的最大子数组 voidmax_sequence(){int ans =-0x3f;int ind;for(int i =0; i < n; i++){
dp[i]= a[i];if(i >0&& dp[i-1]>0){
dp[i]+= dp[i-1];
rec[i]= rec[i-1];}else{
rec[i]= i;}if(dp[i]> ans){
ind = i;
ans = dp[i];}}
cout <<"最大子数组大小:"<< ans << endl;
cout <<"最大子数组(l和r):"<< rec[ind]<<' '<< ind <<" (下标从0开始)"<< endl;}intmain(){
cout <<"数组长度及其序列:"<< endl;
cin >> n;for(int i =0; i < n; i++) cin >> a[i];max_sequence();return0;}
最长公共子序列
#include<iostream>#include<vector>usingnamespace std;constint N =100;char s1[N], s2[N];int c[N][N];int n, m;
string rec2[N][N];
vector<char> res;// 7 6// abcbdab, bdcabavoidLCS(){for(int i =1; i <= n; i++){for(int j =1; j <= m; j++){if(s1[i]!= s2[j]){if(c[i][j-1]>= c[i-1][j]){
c[i][j]= c[i][j-1];
rec2[i][j]="L";}else{
c[i][j]= c[i-1][j];
rec2[i][j]="U";}}else{
c[i][j]= c[i-1][j-1]+1;
rec2[i][j]="LU";}}}
cout <<"最长公共子序列长度: "<< c[n][m]<< endl;while(c[n][m]!=0){if(rec2[n][m]=="U") n--;elseif(rec2[n][m]=="L") m--;else{
res.push_back(s1[n]);
n--, m--;}}for(auto x : res){
cout << x <<' ';}
cout << endl;}intmain(){
cout <<"输入两个子序列:"<< endl;
cin >> n >> m;scanf("%s%s", s1+1, s2+1);LCS();return0;}
最长公共子串
#include<iostream>usingnamespace std;constint N =10010;int n, m;char a[N], b[N];int c[N][N], len, pos;voidprint(){if(len ==0){printf("不存在LCS\n");return;}printf("LCS长度:%d\nLCS:", len);int i = pos - len +1;while(i <= pos)putchar(a[i++]);puts("");}voidsolve(char*a,char*b,int n,int m){for(int i =1; i <= n; i++){for(int j =1; j <= m; j++){if(a[i]== b[j]){
c[i][j]= c[i-1][j-1]+1;if(c[i][j]> len){
len = c[i][j];
pos = i;}}}}print();}/*
7 6
ABCADBB
BCEDBB
*/intmain(){
cin >> n >> m;scanf("%s", a+1);scanf("%s", b+1);solve(a, b, n, m);return0;}
01背包
#include<iostream>usingnamespace std;constint N =10010;int f[N][N];int rec[N][N];int n, m;int v[N], w[N];/*
输入:
5 13
10 24
3 2
4 9
5 10
4 9
*/intmain(){
cin >> n >> m;for(int i =1; i <= n; i++){
cin >> v[i]>> w[i];}// 未优化版本 for(int i =1; i <= n; i++){for(int j =1; j <= m; j++){
f[i][j]= f[i-1][j];if(j >= v[i]){int t = f[i-1][j - v[i]]+ w[i];if(t > f[i][j]){
f[i][j]= t;
rec[i][j]=1;}}}}
cout <<"最大价值为: "<< f[n][m]<< endl;
cout <<"所选方案: ";while(rec[n][m]!=0){
cout << n <<' ';
m -= v[n];
n -=1;}
cout << endl;return0;}
部分背包
#include<iostream>#include<algorithm>usingnamespace std;constint N =10010;/*
5 800
600 60
250 10
200 36
100 16
300 45
*/structgoods{int v, w, i;booloperator<(const goods &b)const{return w / v > b.w / b.v;}} g[N];int n, v;int rec[N];intmain(){
cin >> n >> v;for(int i =1; i <= n; i++){
cin >> g[i].v >> g[i].w;
g[i].i = i;}sort(g+1, g+1+n);int ans =0;for(int i =1; i <= n; i++){if(v > g[i].v){
v -= g[i].v;
ans += g[i].w;
rec[i]= g[i].v;}else{
ans += v * g[i].w / g[i].v;
rec[i]= v;break;}}printf("最大价值为: %d\n", ans);for(int i =1; i <= n; i++){if(rec[i]){printf("选择%d(排序后位置为: %d)%d体积\n", g[i].i, i, rec[i]);}}puts("");return0;}
不带权活动选择问题(贪心)
#include<iostream>#include<algorithm>usingnamespace std;constint N =100010;structseg{int i, l, r;booloperator<(const seg &b)const{return r < b.r;}} s[N];int n;int rec[N];intmain(){
cin >> n;for(int i =1; i <= n; i++){
cin >> s[i].l >> s[i].r;
s[i].i = i;}sort(s+1, s+n+1);int r = s[1].r;int cnt =1;for(int i =2; i <= n; i++){if(s[i].l < r)continue;
cnt++;
r = s[i].r;
rec[i]=1;}printf("选择的数量为:%d\n", cnt);// 追踪printf("排%d原%d (s:%d e%d)\n",1, s[1].i, s[1].l, s[1].r);for(int i =1; i <= n; i++){if(rec[i])printf("排%d原%d (s:%d e%d)\n", i, s[i].i, s[i].l, s[i].r);}return0;}/*
11
1 4
3 5
0 6
5 7
3 9
5 9
6 10
8 11
8 12
2 14
12 16
*/
带权活动选择问题 (dp + 贪心 + 二分)
#include<iostream>#include<algorithm>usingnamespace std;constint N =10010;// 崔剑烁 20201836080 计科H20.1structseg{int idx, l, r, w;booloperator<(const seg &b)const{return r < b.r;}} s[N];int rec[N];// 追踪数组int p[N];// 上一个可以选择的活动区间int n;int f[N];boolp_check(int cur,int mid){if(s[mid].r > s[cur].l)returnfalse;returntrue;}// 二分查找,取得前面最近可以选择的活动区间,记录为p[i].// 二分答案:小于等于当前l的第一个rvoidget_last(){for(int i =1; i <= n; i++){int l =1, r = i;while(l < r){int mid =(l + r +1)>>1;// l = midif(p_check(i, mid)) l = mid;else r = mid -1;}
p[i]= l;}
p[1]=0;}intmain(){
cin >> n;for(int i =1; i <= n; i++){
cin >> s[i].l >> s[i].r >> s[i].w;
s[i].idx = i;}sort(s+1, s+1+n);get_last();// 获取上一个可以选择的活动区间 p[i]for(int i =1; i <= n; i++){
f[i]= f[i-1];if(f[p[i]]+ s[i].w > f[i]){
f[i]= f[p[i]]+ s[i].w;
rec[i]=1;}}// p[i]printf("p数组\n");for(int i =1; i <= n; i++){
cout << p[i]<<' ';}
cout << endl;// f[n] 为最大收益printf("最大收益为: %d\n", f[n]);// 通过rec数组追踪int cur = n;while(cur >0){if(rec[cur]==1){printf("排序序列位置:%d(原序列位置:%d), s:%d, e:%d\n", cur, s[cur].idx, s[cur].l, s[cur].r);
cur = p[cur];}else{
cur -=1;}}return0;}/*
10
1 4 1
3 5 6
0 6 4
4 7 7
3 9 3
5 9 12
6 10 2
8 11 9
8 12 11
2 14 8
*//*
5
7 9 9
7 8 1
6 7 9
6 8 5
4 9 9
5
4 7 9
3 4 4
7 8 8
8 9 6
4 5 9
*/
钢条切割 RCP
#include<iostream>usingnamespace std;constint N =10010, M =10010;int len;int n;int p[N];int c[M];int rec[N];/*
10
1 5 8 9 10 17 17 20 24 24
*/voidprint(){printf("RCP最大收益:%d\n方案:", c[n]);while(rec[n]>0){printf("%d ", rec[n]);
n = n - rec[n];}puts("");}voidsolve(){for(int i =1; i <= n; i++){
c[i]= p[i];for(int j =1; j < i; j++){if(c[i-j]+ p[j]> c[i]){
rec[i]= j;
c[i]= c[i-j]+ p[j];}}}print();}intmain(){
cin >> n;for(int i =1; i <= n; i++) cin >> p[i];solve();return0;}
矩阵链乘法 MCO
#include<iostream>usingnamespace std;constint N =1010;int n;int m[N][N];int rec[N][N];int p[N];voidprint(int l,int r){if(l == r){printf("U%d", l);return;}putchar('(');print(l, rec[l][r]);print(rec[l][r]+1, r);putchar(')');}voidMco(){for(int l =2; l <= n; l++){for(int i =1; i <= n - l +1; i++){int j = i + l -1;
m[i][j]=0x3f3f3f3f;for(int k = i; k < j; k++){int q = m[i][k]+ m[k+1][j]+ p[i-1]*p[k]*p[j];if(q < m[i][j]){
m[i][j]= q;
rec[i][j]= k;}}}}printf("MCO:%d\n", m[1][n]);print(1, n);}intmain(){/*
6
2 3 7 9 5 2 4
6
30 35 15 5 10 20 25
\*/
cin >> n;for(int i =0; i <= n; i++) cin >> p[i];Mco();return0;}
堆优化dijkstra
#include<iostream>#include<cstring>#include<queue>usingnamespace std;typedef pair<int,int> PII;constint N =1e6+10;int n, m;int h[N], e[N], w[N], ne[N], idx;int dist[N];bool st[N];voidadd(int a,int b,int c){
e[idx]= b, w[idx]= c, ne[idx]= h[a], h[a]= idx++;}intdijkstra(){memset(dist,0x3f,sizeof(dist));
dist[1]=0;
priority_queue<PII, vector<PII>, greater<PII>> heap;
heap.push({0,1});while(heap.size()){auto t = heap.top();
heap.pop();int ver = t.second, distance = t.first;if(st[ver])continue;
st[ver]=true;for(int i = h[ver]; i !=-1; i = ne[i]){int j = e[i];if(dist[j]> dist[ver]+ w[i]){
dist[j]= dist[ver]+ w[i];
heap.push({dist[j], j});}}}if(dist[n]==0x3f3f3f3f)return-1;return dist[n];}intmain(){scanf("%d%d",&n,&m);memset(h,-1,sizeof h);while(m--){int a, b, c;scanf("%d%d%d",&a,&b,&c);add(a, b, c);}printf("%d\n",dijkstra());return0;}
bellman-ford
#include<iostream>#include<cstring>#include<algorithm>usingnamespace std;constint N =510, M =10010;structedge{int a, b, c;} edges[M];int n, m, k;int dist[N];int last[N];voidbellman_ford(){memset(dist,0x3f,sizeof(dist));
dist[1]=0;for(int i =0; i < k; i++){memcpy(last, dist,sizeof(dist));for(int j =0; j < m; j++){structedge e = edges[j];
dist[e.b]=min(dist[e.b], last[e.a]+ e.c);}}}intmain(){scanf("%d%d%d",&n,&m,&k);for(int i =0; i < m; i++){int a, b, c;scanf("%d%d%d",&a,&b,&c);
edges[i]={a, b, c};}bellman_ford();if(dist[n]>0x3f3f3f3f/2)puts("impossible");elseprintf("%d\n", dist[n]);return0;}
prim 求最小生成树
#include<cstring>#include<iostream>#include<algorithm>usingnamespace std;constint N =510, INF =0x3f3f3f3f;int n, m;int g[N][N];int dist[N];bool st[N];intprim(){memset(dist,0x3f,sizeof dist);int res =0;for(int i =0; i < n; i ++){int t =-1;for(int j =1; j <= n; j ++)if(!st[j]&&(t ==-1|| dist[t]> dist[j]))
t = j;if(i && dist[t]== INF)return INF;if(i) res += dist[t];
st[t]=true;for(int j =1; j <= n; j ++) dist[j]=min(dist[j], g[t][j]);}return res;}intmain(){scanf("%d%d",&n,&m);memset(g,0x3f,sizeof g);while(m --){int a, b, c;scanf("%d%d%d",&a,&b,&c);
g[a][b]= g[b][a]=min(g[a][b], c);}int t =prim();if(t == INF)puts("impossible");elseprintf("%d\n", t);return0;}
kruskal求最小生成树 (并查集优化)
#include<iostream>#include<algorithm>usingnamespace std;constint N =200010;structedge{int s, e, v;booloperator<(const edge &b)const{returnthis->v < b.v;}} edges[N];int pred[N];int preds[N];int n, m, ans, cnt, p[N];intfind(int x){if(p[x]!= x) p[x]=find(p[x]);return p[x];}
string s ="0abcdfghiz";
string ss ="1 2 3 4 5 6 7 8 9";/*
1 2 3 4 5 6 7 8 9 依次代表 a b c d f g h i z
输入:
9 14
1 2 4
1 7 8
2 7 1
2 3 8
7 8 7
7 6 1
6 8 4
8 3 2
3 4 7
3 5 4
6 5 2
5 4 14
4 9 9
5 9 10
*/intmain(){scanf("%d%d",&n,&m);for(int i =0; i < m; i++){
cin >> edges[i].s >> edges[i].e >> edges[i].v;}sort(edges, edges + m);for(int i =1; i <= n; i++){
p[i]= i;}for(int i =0; i < m; i++){int s = edges[i].s, e = edges[i].e, v = edges[i].v;int a =find(s), b =find(e);if(a != b){
p[a]= b;
pred[e]= s;
preds[e]= v;
ans += v;
cnt++;}}if(cnt == n -1){printf("%d\n", ans);}else{puts("impossible");}
cout <<"a b c d f g h i z"<< endl;for(int i =1; i <= n; i++)printf("%d ", preds[i]);puts("");for(int i =1; i <= n; i++)printf("%c ", s[pred[i]]);return0;}