链表
单向链表acwing826
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
| #include<iostream>
using namespace std;
const int N = 1e5 + 10; int head, idx, e[N], ne[N];
void init(){ head = -1; idx = 0; }
void add_to_head(int x){ e[idx] = x, ne[idx] = head; head = idx; idx++; }
void add(int k, int x){ e[idx] = x, ne[idx] = ne[k]; ne[k] = idx; idx++; }
void remove(int k){ ne[k] = ne[ne[k]]; }
void print(){ for(int i = head; i != -1; i = ne[i]){ cout << e[i] << " "; } cout << endl; }
int main(){ init(); int m; char a; int b,c; cin >> m; for(int i=0;i<m;i++){ cin >> a; if (a=='H'){ cin >> b; add_to_head(b); }else if(a=='D'){ cin >> b; if(!b) head = ne[head]; else remove(b-1); }else{ cin >> b >> c; add(b-1,c); } } print(); }
|
双向链表acwing827
这代码写的太美了acwing827 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| #include<iostream> #include<string>
using namespace std;
const int N = 1e5 + 10; int idx, e[N], l[N], r[N];
void init(){ r[0] = 1; l[1] = 0; idx = 2; }
void add(int k, int x){ e[idx] = x; l[idx] = k; r[idx] = r[k]; l[r[k]] = idx; r[k] = idx; idx++; }
void remove(int k){ r[l[k]] = r[k]; l[r[k]] = l[k]; }
int main(){ init(); string op; int k, x, m; cin >> m; for (int i = 0; i < m; i++){ cin >> op; if(op == "L"){ cin >> x; add(0, x); }else if(op == "R"){ cin >> x; add(l[1], x); }else if(op == "IL"){ cin >> k >> x; add(l[k+1], x); }else if(op == "IR"){ cin >> k >> x; add(k+1, x); }else{ cin >> k; remove(k+1); } } for(int i=r[0];i!=1;i=r[i]) cout<<e[i]<<' '; cout << endl; }
|
0-1背包
acwing
讲的很好 用集合来理解
不化为一维可以使用2维的滚动数组,理解起来更加简单。
一行存旧值,一行赋新值。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| #include<iostream> #include<algorithm>
using namespace std;
const int N = 1010; int n,m; int v[N], w[N]; int f[N][N];
int f2[N];
int main(){ 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 (v[i]<=j) f[i][j] = max(f[i][j], f[i-1][j-v[i]]+w[i]); }
for(int i=1;i<=n;i++) for (int j = m;j>=v[i];j--){ f2[j] = max(f2[j], f2[j-v[i]]+w[i]); } cout << f[n][m] << ' '<<f2[m]<<endl;
}
|
完全背包
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
for(int i=1;i<=n;i++){ for(int j =1;j<=m;j++){ for(int k=0;v[i]*k<=j;k++){ f[i][j] = max(f[i][j], f[i-1][j-k*v[i]]+k*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]) f[i][j] = max(f[i][j], f[i][j-v[i]]+w[i]); } }
for(int i=1;i<=n;i++){ for(int j =v[i];j<=m;j++){ f[j] = max(f[j], f[j-v[i]]+w[i]); } } cout << f[n][m] << endl;
|
注意为什么01与完全的j的遍历顺序为什么不同。
多重背包问题
二进制优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| #include<iostream> #include<algorithm>
using namespace std;
const int N = 1010; int n,m; int v[N], w[N]; int f[N];
int main(){ int cnt = 0; cin >> n>> m; for(int i=1;i<=n;i++){ int vi,wi,ci; cin >> vi >> wi >> ci; int k = 1; while(k<=ci){ cnt++; v[cnt] = vi*k; w[cnt] = wi*k; ci-=k; k = k*2; } if(ci>0){ cnt++; v[cnt] = vi*ci; w[cnt] = wi*ci; } } for(int i=1;i<=cnt;i++){ for(int j=m;j>=v[i];j--){ f[j] = max(f[j], f[j-v[i]]+w[i]); } }
cout << f[m] << endl; }
|
多重背包问题
朴素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| #include<iostream> #include<algorithm>
using namespace std;
const int N = 110; int v[N][N], w[N][N], s[N]; int f[N][N]; int n, m;
int main(){ cin>>n>>m; for(int i=1;i<=n;i++){ cin >> s[i]; for(int j=1;j<=s[i];j++){ cin >> v[i][j] >> w[i][j]; } }
for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ f[i][j] = f[i-1][j]; for(int k=1;k<=s[i];k++){ if(v[i][k]<=j) f[i][j] = max(f[i][j], f[i-1][j-v[i][k]]+w[i][k]); } } } cout << f[n][m] << endl; }
|
优化f
1 2 3 4 5 6 7 8 9
| for(int i=1;i<=n;i++){ for(int j=m;j>=1;j--){ for(int k=1;k<=s[i];k++){ if(v[i][k]<=j) f[j] = max(f[j], f[j-v[i][k]]+w[i][k]); } } }
|