背包问题C++代码
关于背包问题的理解,请参考我的随笔: https://www.cnblogs.com/jmliao/p/9241091.html
下面给出C++代码
#include <iostream> #include <iomanip> using namespace std; #define MAX(a,b) (((a) > (b)) ? (a) : (b)) #define N 100 //N>=资源总量+1 int cost[N]; //每种物品的代价 int value[N]; //每种物品的价值 int num[N]; //每种物品的数量 int dp[N]; //动态规划数组 int flags[N]; //记录被使用的物品种类及数量 void print_dp(int dp[], int m) { for (int i = 0; i <= m; i++) cout << left<<setw(4)<<dp[i]; cout << endl; } void init_dp() { for (int i = 0; i < N; i++) dp[i] = 0; } //01背包 void ZeroOne_Pack(int cost, int value, int m) { for (int j = m; j >= cost; j--) dp[j] = MAX(dp[j], dp[j - cost] + value); } //完全背包 void Complete_Pack(int cost, int value, int m) { for (int j = cost; j <= m; j++) dp[j] = MAX(dp[j], dp[j - cost] + value); } //多重背包 int Multi_Pack(int cost[], int value[], int num[], int n, int m) { init_dp(); for (int i = 1; i <= n; i++) //遍历每种物品 { if (num[i] * cost[i] > m) { Complete_Pack(cost[i], value[i], m); //如果全装进去已经超了重量,相当于这个物品就是无限的 print_dp(dp,m); } else { int k = 1, num_i=num[i]; //初始化k为1,二进制压缩遍历次数(logk) while (k < num_i) { ZeroOne_Pack(k*cost[i], k*value[i], m); print_dp(dp,m); num_i -= k; k <<= 1; } ZeroOne_Pack(num_i * cost[i], num_i * value[i], m); print_dp(dp,m); } } return dp[m]; } int main() { int m, n; cout << "物品种类: "; cin >> n; cout << "资源总量: "; cin >> m; cout << "\n代价 价值 数量" << endl; for (int i = 1; i <= n; i++) cin >> cost[i] >> value[i] >> num[i]; cout << "最大价值: " << Multi_Pack(cost, value, num, n, m) << endl; return 0; }