2.完全背包问题

2.完全背包问题_第1张图片

2.完全背包问题_第2张图片

 完全背包问题是每件物品有无限个

完全背包问题的状态表示和01背包问题一样

dp[i][j]表示只看前i个物品,总体积<= j的最大价值

状态计算:

  按照第i个物品选了多少个来分

2.完全背包问题_第3张图片

2.完全背包问题_第4张图片

 然后综合起来就是

k是枚举的第i个物品的个数,k = 0, 1, 2,...

三层循环的二维做法

 1 #include 
 2 using namespace std;
 3 const int N = 1010;
 4 int dp[N][N];
 5 int v[N], w[N];
 6 int main() {
 7     int n, m;
 8     cin >> n >> m;
 9     for (int i = 1; i <= n; i++) {
10         cin >> v[i] >> w[i];
11     }
12     for (int i = 1; i <= n; i++) {
13         for (int j = 0; j <= m; j++) {
14             for (int k = 0; k * v[i] <= j; k++) { //枚举一下物品个数,k个物品一定要小于等于j 
15                 dp[i][j] = max(dp[i][j], dp[i - 1][j - v[i] * k] + w[i] * k);
16             }
17         }
18     }
19     cout << dp[n][m] << endl;
20     return 0;
21 }

完全背包问题可以优化乘两层循环

2.完全背包问题_第5张图片

 这是两层循环,二维的解法

 1 #include 
 2 using namespace std;
 3 const int N = 1010;
 4 int dp[N][N];
 5 int v[N], w[N];
 6 int main() {
 7     int n, m;
 8     cin >> n >> m;
 9     for (int i = 1; i <= n; i++) {
10         cin >> v[i] >> w[i];
11     }
12     for (int i = 1; i <= n; i++) {
13         for (int j = 0; j <= m; j++) {
14             dp[i][j] = dp[i - 1][j];
15             if (j >= v[i]) {
16                 dp[i][j] = max(dp[i][j], dp[i][j - v[i]] + w[i]);
17             }
18         }
19     }
20     cout << dp[n][m] << endl;
21     return 0;
22 }

完全背包问题也可以优化到一维

 1 #include 
 2 using namespace std;
 3 const int N = 1010;
 4 int dp[N];
 5 int v[N], w[N];
 6 int main() {
 7     int n, m;
 8     cin >> n >> m;
 9     for (int i = 1; i <= n; i++) {
10         cin >> v[i] >> w[i];
11     }
12     for (int i = 1; i <= n; i++) {
13         for (int j = v[i]; j <= m; j++) {
14             dp[j] = max(dp[j], dp[j - v[i]] + w[i]);
15         }
16     }
17     cout << dp[m] << endl;
18     return 0;
19 }

 

你可能感兴趣的:(2.完全背包问题)