赞
踩
例子:给你一堆物品,每个物品有一定的体积,每个物品只能选一个,求总体积不超过 m的方案数
输入
4 5
2 2 3 7
输出
7
二维代码
#include <bits/stdc++.h> using namespace std; const int N = 100; int f[N][N]; int n, m; int main() { cin >> n >> m; /*初始化 当 0 个物品,体积不超过 i 的方案数, 即不选为1种方案 , 即 i 从 0 - m 初始化 1 1 2 2 2 2 //不选时从上一状态转移过来,选时则有 叠加 1 ,表示当前选与不选两种方案 1 1 3 3 4 4 1 1 3 4 5 7 1 1 3 4 5 7 */ for (int i = 0; i <= m; i ++ ) f[0][i] = 1; for (int i = 1; i <= n; i ++ ) { int v; cin >> v; for (int j = 0; j <= m; j ++ ) { f[i][j] = f[i-1][j]; //不选的方案数 if (j >= v) f[i][j] += f[i-1][j-v]; //加上满足可以选的方案数 } } cout << f[n][m]; return 0; }
状态压缩
#include <bits/stdc++.h> using namespace std; const int N = 100; int f[N]; int n, m; int main() { cin >> n >> m; //初始化 当 0 个物品,体积不超过 i 的方案数, 即不选为1种方案 , 即 i 从 0 - m 初始化 for (int i = 0; i <= m; i ++ ) f[i] = 1; for (int i = 1; i <= n; i ++ ) { int v; cin >> v; for (int j = m; j >= v; j -- ) { f[j] += f[j - v]; } } cout << f[m]; return 0; }
例子:给你一堆物品,每个物品有一定的体积,每个物品可以选无数多个,求总体积不超过 m 的方案数
输入
3 5
2 3 7
输出
5
二维代码
#include <bits/stdc++.h> using namespace std; const int N = 100; int n, m; int f[N][N]; int main() { cin >> n >> m; /* 同理,需要注意的时,本来加上的是当前物品不选,或者选一个,两个。。。的方案数 在经过状态压缩后,只需要加上 f[i][j - v]即可 */ for (int i = 0; i <= m; i ++ ) f[0][i] = 1; for (int i = 1; i <= n; i ++ ) { int v; cin >> v; for (int j = 0; j <= m; j ++ ) { f[i][j] = f[i-1][j]; if (j >= v) f[i][j] += f[i][j-v]; } } cout << f[n][m]; return 0; }
状态压缩
#include <bits/stdc++.h> using namespace std; const int N = 100; int n, m; int f[N]; int main() { cin >> n >> m; /* 注意这里的状态转移,不懂可以看上面给出的连接,在背包最大最小值问题里面有讲解 */ for (int i = 0; i <= m; i ++ ) f[i] = 1; for (int i = 1; i <= n; i ++ ) { int v; cin >> v; for (int j = v; j <= m; j ++ ) { f[j] += f[j - v]; } } cout << f[m]; return 0; }
注:在此情况下,当的 f[i][j] = 1 时,表示只能恰好由自己组成一种方案,不能选其他物品
例子:给你一堆物品,每个物品有一定的体积,每个物品只能选一个,求总体积恰好是 m 的方案数
输入
4 5
2 2 3 7
输出
2
二维代码
#include <bits/stdc++.h> using namespace std; const int N = 100; int n, m; int f[N][N]; int main() { cin >> n >> m; /* 只能将f[0][0] 初始化为 1, 这样才能保证当 j 恰好等于物品体积时才有方案数可加。 其余均加 0, 即不满足恰好等于 */ f[0][0] = 1; for (int i = 1; i <= n; i ++ ) { int v; cin >> v; for (int j = 0; j <= m; j ++ ) { f[i][j] = f[i-1][j]; if (j >= v) f[i][j] += f[i-1][j-v]; } } cout << f[n][m]; return 0; }
状态压缩
#include <bits/stdc++.h> using namespace std; const int N = 100; int n, m; int f[N]; int main() { cin >> n >> m; f[0] = 1; for (int i = 1; i <= n; i ++ ) { int v; cin >> v; for (int j = m; j >= v; j -- ) { f[j] += f[j - v]; } } cout << f[m]; return 0; }
例子:给你一堆物品,每个物品有一定的体积,每个物品可以选无数多个,求总体积恰好是 m 的方案数
输入
3 5
2 3 7
输出
1
二维代码
#include <iostream> using namespace std; const int N = 110; int n, m; int f[N][N]; int main() { cin >> n >> m; f[0][0] = 1; for (int i = 1; i <= n; i ++ ) { int v; cin >> v; for (int j = 0; j <= m; j ++ ) { f[i][j] = f[i - 1][j]; if(j >= v) f[i][j] += f[i][j - v]; } } cout << f[n][m]; return 0; }
状态压缩
#include <iostream> using namespace std; const int N = 110; int n, m; int f[N]; int main() { cin >> n >> m; f[0] = 1; for (int i = 1 ;i <= n; i ++ ) { int v; cin >> v; for (int j = v ;j <= m; j ++ ) { f[j] = f[j] + f[j - v]; } } cout << f[m] << endl; return 0; }
例子:给你一堆物品,每个物品有一定的体积,每个物品只能选一个,求总体积至少是m的方案数
输入
3 5
2 3 7
输出
5
二维代码
#include <bits/stdc++.h> using namespace std; const int N = 110; int n, m; int f[N][N]; int main() { cin >> n >> m; f[0][0] = 1; for (int i = 1; i <= n; i ++ ) { int v; cin >> v; for (int j = 0; j <= m; j ++ ) { f[i][j] = f[i - 1][j] + f[i - 1][max(0, j - v)]; } } cout << f[n][m]; return 0; }
状态压缩
#include <bits/stdc++.h> using namespace std; const int N = 110; int n, m; int f[N]; int main() { cin >> n >> m; f[0] = 1; for (int i = 1; i <= n; i ++ ) { int v; cin >> v; for (int j = m; j >= 0; j -- ) { f[j] += f[max(0, j - v)]; } } cout << f[m]; return 0; }
例子:给你一堆物品,每个物品有一定的体积,每个物品可以选无数多个,求总体积至少是 m 的方案数
答案:无穷多种方案数
二维实现以及状态压缩
1、体积至多 j,f[0][i] = 1, 0 <= i <= m,其余是0 , 状态压缩后:f[i] = 1, 0 <= i <= m,
2、体积恰好 j,f[0][0] = 1, 其余是0, 状态压缩后:f[0] = 1, 其余是0
3、体积至少 j,f[0][0] = 1,其余是0, 状态压缩后:f[0] = 1, 其余是0
如有错误之处,欢迎各位指正~~~
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。