是听了y总 算法基础课 的笔记,纯纯记录
背包问题
1、01背包 每件物品只有一个
2、完全背包 每件物品有无限个
3、多重背包 每件物品有有限个(个数已知)
4、分组背包 有若干组物品,每组有若干个,每组最多选一个
01背包
未优化代码
#include#include using namespace std; const int N = 1005; int n ,m; int v[N], w[N]; int f[N][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 = 0; 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]); } cout << f[n][m] << endl; return 0; }
优化代码
#include#include using namespace std; const int N = 1005; int n ,m; int v[N], w[N]; int f[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 = m; j >= v[i]; j--) f[j] = max(f[j], f[j-v[i]]+w[i]); cout << f[m] << endl; return 0; }
完全背包
未优化代码
#include#include using namespace std; const int N = 1005; int n ,m; int v[N], w[N]; int f[N][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 = 0; 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]); } cout << f[n][m] << endl; return 0; }
优化代码
#include#include using namespace std; const int N = 1005; int n ,m; int v[N], w[N]; int f[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 = v[i]; j <= m; j++) f[j] = max(f[j], f[j-v[i]]+w[i]); cout << f[m] << endl; return 0; }
多重背包
多重背包1
#include#include using namespace std; const int N = 105; int n,m; int v[N], w[N], s[N]; int f[N][N]; int main() { cin >> n >> m; for(int i=1; i<=n; i++) cin >> v[i] >> w[i] >>s[i]; for(int i=1; i<=n; i++) for(int j=0; j<=m; j++) for(int k=0; k*v[i]<=j && k<=s[i]; k++) f[i][j] =max(f[i][j], f[i-1][j-k*v[i]]+k*w[i]); cout << f[n][m] << endl; return 0; }
多重背包2
#include#include using namespace std; const int N = 12005, M = 2005; int n,m; int v[N], w[N]; int f[N]; int main() { cin >> n >> m; int cnt = 0; for(int i=1; i<=n; i++) { int a,b,s; cin >> a >> b >> s; int k = 1; while(k<=s) { cnt++; v[cnt] = a*k; w[cnt] = b*k; s = s-k; k = k*2; } if(s>0) { cnt++; v[cnt] = a*s; w[cnt] = b*s; } } n = cnt; for(int i=1; i<=n; i++) for(int j=m; j>=v[i]; j--) f[j] = max(f[j], f[j-v[i]]+w[i]); cout << f[m] << endl; return 0; }
分组背包
代码
#include#include using namespace std; const int N = 105; int n, m; int s[N]; int v[N][N], w[N][N]; int f[N]; int main() { cin >> n >> m; for(int i=1; i<=n; i++) { cin >> s[i]; for(int j=0; j > v[i][j] >> w[i][j]; } for(int i=1; i<=n; i++) for(int j=m; j>=0; j--) for(int k=0; k



