题目:Acwing2. 01背包问题
链接:https://www.acwing.com/problem/content/2/
思路:
AC代码:
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn = 1005;
int n, V;
int v[maxn], w[maxn];
int f[maxn];
int main(void) {
// freopen("in.txt", "r", stdin);
scanf("%d%d", &n, &V);
for(int i = 1; i <= n; i ++)
scanf("%d%d", &v[i], &w[i]);
for(int i = 1; i <= n; i ++)
for(int j = V; j >= v[i]; j --)
f[j] = max(f[j], f[j - v[i]] + w[i]);
printf("%d\n", f[V]);
// fclose(stdin);
return 0;
}
题目:Acwing423. 采药
链接:https://www.acwing.com/problem/content/425/
思路:
AC代码:
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn = 105;
int T, M;
int t[maxn], w[maxn];
int f[1005];
int main(void) {
// freopen("in.txt", "r", stdin);
scanf("%d%d", &T, &M);
for(int i = 1; i <= M; i ++)
scanf("%d%d", &t[i], &w[i]);
for(int i = 1; i <= M; i ++)
for(int j = T; j >= t[i]; j --)
f[j] = max(f[j], f[j - t[i]] + w[i]);
printf("%d\n", f[T]);
// fclose(stdin);
return 0;
}
题目:Acwing426. 开心的金明
题目链接:https://www.acwing.com/problem/content/428/
思路:
AC代码:
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn = 30;
int n, m;
int money[maxn], w[maxn];
int f[30005];
int main(void) {
// freopen("in.txt", "r", stdin);
scanf("%d%d", &n, &m);
for(int i = 1; i <= m; i ++)
scanf("%d%d", &money[i], &w[i]);
for(int i = 1; i <= m; i ++)
for(int j = n; j >= money[i]; j --)
f[j] = max(f[j], f[j - money[i]] + money[i] * w[i]);
printf("%d\n", f[n]);
// fclose(stdin);
return 0;
}
题目:Acwing1022. 宠物小精灵之收服
题目链接:https://www.acwing.com/problem/content/1024/
思路:
AC代码:
#include <iostream>
#include <cstdio>
using namespace std;
int n, m, k;
int c_n[105], c_b[105];
int f[505][1005], vis[505][1005];
int main(void) {
// freopen("in.txt", "r", stdin);
scanf("%d%d%d", &n, &m, &k);
for(int i = 1; i <= k; i ++)
scanf("%d%d", &c_n[i], &c_b[i]);
for(int i = 1; i <= k; i ++) //精灵种类
for(int j = m; j >= c_b[i]; j --) //消耗的体力
for(int cnt = n; cnt >= c_n[i]; cnt --) //消耗的精灵球
if(f[j - c_b[i]][cnt - c_n[i]] + 1 > f[j][cnt]) {
f[j][cnt] = f[j - c_b[i]][cnt - c_n[i]] + 1;
vis[j][cnt] = vis[j - c_b[i]][cnt - c_n[i]] + c_b[i];
} else if(f[j - c_b[i]][cnt - c_n[i]] + 1 == f[j][cnt]) {
vis[j][cnt] = min(vis[j - c_b[i]][cnt - c_n[i]] + c_b[i], vis[j][cnt]);
}
printf("%d %d\n", f[m][n], m - vis[m][n]);
// fclose(stdin);
return 0;;
}
题目:Acwing1024. 装箱问题
题目链接:https://www.acwing.com/problem/content/1026/
相当于把体积数组和价值数组合成了一个数组
AC代码:
#include <iostream>
#include <cstdio>
using namespace std;
int V, n;
int v[35];
int f[20005];
int main(void) {
// freopen("in.txt", "r", stdin);
scanf("%d%d", &V, &n);
for(int i = 1; i <= n; i ++) scanf("%d", &v[i]);
for(int i = 1; i <= n; i ++)
for(int j = V; j >= v[i]; j --)
f[j] = max(f[j], f[j - v[i]] + v[i]);
printf("%d\n", V - f[V]);
// fclose(stdin);
return 0;
}
题目:Acwing7. 混合背包问题
题目链接:https://www.acwing.com/problem/content/7/
思路:
遇到了完全背包和01背包的时候就照常就可以了,但是这道题目我们需要优化一下多重背包的时间复杂度,这李我用的是二进制优化,降了一维的时间复杂度
注意点:
1.数组要开的足够大
AC代码:
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn = 1e4 + 5;
int N, V;
int v[maxn], w[maxn], id[maxn];
int f[maxn][1005];
int cnt;
int main(void) {
// freopen("in.txt", "r", stdin);
scanf("%d%d", &N, &V);
for(int i = 1; i <= N; i ++)
scanf("%d%d%d", &v[i], &w[i], &id[i]);
cnt = N;
for(int i = 1; i <= N; i ++)
if(id[i] > 0) {
int s = id[i], k = 1;
while(k <= s) {
cnt ++;
v[cnt] = k * v[i];
w[cnt] = k * w[i];
id[cnt] = -1;
s -= k;
k <<= 1;
}
if(s) {
cnt ++;
v[cnt] = s * v[i];
w[cnt] = s * w[i];
id[cnt] = -1;
}
}
N = cnt;
for(int i = 1; i <= N; i ++)
for(int j = 1; j <= V; j ++) {
int idd = id[i];
if(idd == -1) {
f[i][j] = f[i - 1][j];
if(j >= v[i]) f[i][j] = max(f[i][j], f[i - 1][j - v[i]] + w[i]);
} else if(idd == 0) {
f[i][j] = f[i - 1][j];
if(j - v[i] >= 0) f[i][j] = max(f[i][j], f[i][j - v[i]] + w[i]);
} else f[i][j] = f[i - 1][j];
}
printf("%d\n", f[N][V]);
// fclose(stdin);
return 0;
}