動態規划之背包九講


背包九講

背包九講鏈接:https://www.cnblogs.com/jbelial/articles/2116074.html

01背包:

題目鏈接:https://www.acwing.com/problem/content/2/

二維數組優化前:

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

優化后:

#include <iostream>
#include <algorithm>


using namespace std;

const int N = 1e3 + 10;
int v[N], w[N];
int f[N];

int main() {
    int N, V;
    cin >> N >> V;
    for (int i = 1; i <= N; i++)    cin >> 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]);
    cout << f[V] << endl;
    return 0;
}
View Code

完全背包:

題目鏈接:https://www.acwing.com/problem/content/3/

優化前:

#include <iostream>


using namespace std;

const int maxn = 1e3 + 10;
int v[maxn], w[maxn];
int f[maxn][maxn];

int main() {
    int N, V;
    cin >> N >> V;
    for (int i = 1; i <= N; i++)    cin >> v[i] >> w[i];
    for (int i = 1; i <= N; i++)
        for (int j = 1; j <= V; 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][V] << endl;
    return 0;
}
View Code

優化后:

#include <iostream>


using namespace std;

const int N = 1e3 + 10;
int v[N], w[N];
int f[N];

int main() {
    int n, V;
    cin >> n >> V;
    for (int i = 1; i <= n; i++)    cin >> v[i] >> w[i];
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= V; j++) 
            if (j >= v[i])  f[j] = max(f[j], f[j - v[i]] + w[i]);
    cout << f[V] << endl;
    return 0;
}
View Code

多重背包:

題目鏈接:https://www.acwing.com/problem/content/4/

數據范圍小,不用優化:

#include <iostream>


using namespace std;

const int N = 1e2 + 10;
int v[N], w[N], s[N];
int f[N];

int main() {
    int n, V;
    cin >> n >> V;
    for (int i = 1; i <= n; i++)    cin >> v[i] >> w[i] >> s[i];
    for (int i = 1; i <= n; i++)
        for (int j = V; j >= 0; j--)
            for (int k = 1; k <= s[i] && k * v[i] <= j; k++)
                f[j] = max(f[j], f[j - k * v[i]] + k * w[i]);
    cout << f[V] << endl;
    return 0;
}
View Code

數據范圍大,二進制優化版:https://www.acwing.com/problem/content/5/

把每個物品拆開

 1 #include <iostream>
 2 
 3 
 4 using namespace std;
 5 
 6 const int N = 25000;
 7 int v[N], w[N];
 8 int f[N];
 9 
10 int main() {
11     int n, V;
12     cin >> n >> V;
13     int cnt = 0;
14     for (int i = 1; i <= n; i++) {
15         int a, b, s;
16         cin >> a >> b >> s;
17         int k = 1;
18         while (k <= s) {
19             cnt++;
20             v[cnt] = a * k;
21             w[cnt] = b * k;
22             s -= k;
23             k *= 2;
24         }
25         if (s > 0) {
26             cnt++;
27             v[cnt] = a * s;
28             w[cnt] = b * s;
29         }
30     }
31     n = cnt;            //因為這句話WA了
32     for (int i = 1; i <= n; i++)
33         for (int j = V; j >= v[i]; j--)
34             f[j] = max(f[j], f[j - v[i]] + w[i]);
35     cout << f[V] << endl;            
36 }
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM