teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

7

追記2

2021/11/08 11:24

投稿

kazuma-s
kazuma-s

スコア8222

answer CHANGED
@@ -74,4 +74,77 @@
74
74
  ks.solve();
75
75
  ks.output();
76
76
  }
77
+ ```
78
+ **追記2**
79
+ n個のアイテムをナップサックに入れるか入れないかを 1 か 0 で表すと、
80
+ 全列挙とは nビットの数値(00...000~11...111)になります。
81
+ 11...111 は、(1<<n) - 1。
82
+ ```C++
83
+ #include <iostream>
84
+ #include <fstream>
85
+ #include <vector>
86
+ using namespace std;
87
+
88
+ class Knapsack {
89
+ int n, capa, best_profit, best_weight;
90
+ vector<int> p, w, item, best;
91
+ public:
92
+ bool input(const char* fname) {
93
+ ifstream ifs(fname);
94
+ if (!ifs) return false;
95
+ ifs >> n;
96
+ p.resize(n);
97
+ w.resize(n);
98
+ for (int i = 0; i < n; i++) ifs >> p[i];
99
+ for (int i = 0; i < n; i++) ifs >> w[i];
100
+ ifs >> capa;
101
+ best_profit = 0;
102
+ item.resize(n);
103
+ best.resize(n);
104
+ return true;
105
+ }
106
+
107
+ void solve() {
108
+ int m = 1 << n;
109
+ for (int bp = 0; bp < m; bp++) { // bit pattern
110
+ int profit = 0, weight = 0;
111
+ for (int i = 0; i < n; i++) {
112
+ if (bp>>i & 1) {
113
+ item[i] = 1;
114
+ profit += p[i];
115
+ weight += w[i];
116
+ }
117
+ else item[i] = 0;
118
+ }
119
+ if (weight <= capa && profit > best_profit) {
120
+ best = item;
121
+ best_profit = profit;
122
+ best_weight = weight;
123
+ }
124
+ }
125
+ }
126
+
127
+ void output() {
128
+ cout << "item:";
129
+ for (int i = 0; i < n; i++)
130
+ if (best[i]) cout << " " << i+1;
131
+ cout << "\n" "profit = " << best_profit
132
+ << " weight = " << best_weight << "\n";
133
+ }
134
+ };
135
+
136
+ int main(int argc, char *argv[])
137
+ {
138
+ if (argc != 2) {
139
+ cout << "usage: " << argv[0] << " file_name\n";
140
+ return 1;
141
+ }
142
+ Knapsack ks;
143
+ if (!ks.input(argv[1])) {
144
+ cout << "can't open " << argv[1] << "\n";
145
+ return 1;
146
+ }
147
+ ks.solve();
148
+ ks.output();
149
+ }
77
150
  ```

6

コードの修正

2021/11/08 11:24

投稿

kazuma-s
kazuma-s

スコア8222

answer CHANGED
@@ -22,7 +22,7 @@
22
22
  public:
23
23
  bool input(const char* fname) {
24
24
  ifstream ifs(fname);
25
- if (!ifs) false;
25
+ if (!ifs) return false;
26
26
  ifs >> n;
27
27
  p.resize(n);
28
28
  w.resize(n);
@@ -67,7 +67,10 @@
67
67
  return 1;
68
68
  }
69
69
  Knapsack ks;
70
- if (!ks.input(argv[1])) return 1;
70
+ if (!ks.input(argv[1])) {
71
+ cout << "can't open " << argv[1] << "\n";
72
+ return 1;
73
+ }
71
74
  ks.solve();
72
75
  ks.output();
73
76
  }

5

クラス名の変更

2021/11/08 00:58

投稿

kazuma-s
kazuma-s

スコア8222

answer CHANGED
@@ -16,7 +16,7 @@
16
16
  #include <vector>
17
17
  using namespace std;
18
18
 
19
- class DP {
19
+ class Knapsack {
20
20
  int n, capa, max_profit, max_weight;
21
21
  vector<int> p, w, u, best;
22
22
  public:
@@ -66,9 +66,9 @@
66
66
  cout << "usage: " << argv[0] << " file_name\n";
67
67
  return 1;
68
68
  }
69
- DP dp;
69
+ Knapsack ks;
70
- if (!dp.input(argv[1])) return 1;
70
+ if (!ks.input(argv[1])) return 1;
71
- dp.solve();
71
+ ks.solve();
72
- dp.output();
72
+ ks.output();
73
73
  }
74
74
  ```

4

コードの修正

2021/11/07 20:53

投稿

kazuma-s
kazuma-s

スコア8222

answer CHANGED
@@ -20,8 +20,6 @@
20
20
  int n, capa, max_profit, max_weight;
21
21
  vector<int> p, w, u, best;
22
22
  public:
23
- DP() : n(-1) { }
24
-
25
23
  bool input(const char* fname) {
26
24
  ifstream ifs(fname);
27
25
  if (!ifs) false;

3

コードの修正

2021/11/07 20:47

投稿

kazuma-s
kazuma-s

スコア8222

answer CHANGED
@@ -37,8 +37,6 @@
37
37
  return true;
38
38
  }
39
39
 
40
- bool fail() { return n < 0; }
41
-
42
40
  void step(int i, int profit, int weight) {
43
41
  if (i == n) {
44
42
  if (weight <= capa && profit > max_profit) {

2

コードの修正

2021/11/07 20:46

投稿

kazuma-s
kazuma-s

スコア8222

answer CHANGED
@@ -44,7 +44,7 @@
44
44
  if (weight <= capa && profit > max_profit) {
45
45
  max_profit = profit;
46
46
  max_weight = weight;
47
- for (i = 0; i < n; i++) best[i] = u[i];
47
+ best = u;
48
48
  }
49
49
  }
50
50
  else if (weight <= capa) {

1

追記

2021/11/07 20:41

投稿

kazuma-s
kazuma-s

スコア8222

answer CHANGED
@@ -6,4 +6,73 @@
6
6
  i は 0~(n-1)、j は 0~(capa-1) でなければなりません。
7
7
  dp[n][y] = 0; の n は範囲外であり、y も capa になるので範囲外です。
8
8
  これが segmentation fault の原因です。
9
- w[i] も i は 1~(n-1) でないといけないのに w[n] を参照しています。
9
+ w[i] も i は 1~(n-1) でないといけないのに w[n] を参照しています。
10
+
11
+ **追記**
12
+ 関数の引数が多いのは面倒なので、クラスを使ってみました。
13
+ ```C++
14
+ #include <iostream>
15
+ #include <fstream>
16
+ #include <vector>
17
+ using namespace std;
18
+
19
+ class DP {
20
+ int n, capa, max_profit, max_weight;
21
+ vector<int> p, w, u, best;
22
+ public:
23
+ DP() : n(-1) { }
24
+
25
+ bool input(const char* fname) {
26
+ ifstream ifs(fname);
27
+ if (!ifs) false;
28
+ ifs >> n;
29
+ p.resize(n);
30
+ w.resize(n);
31
+ for (int i = 0; i < n; i++) ifs >> p[i];
32
+ for (int i = 0; i < n; i++) ifs >> w[i];
33
+ ifs >> capa;
34
+ max_profit = 0;
35
+ u.resize(n);
36
+ best.resize(n);
37
+ return true;
38
+ }
39
+
40
+ bool fail() { return n < 0; }
41
+
42
+ void step(int i, int profit, int weight) {
43
+ if (i == n) {
44
+ if (weight <= capa && profit > max_profit) {
45
+ max_profit = profit;
46
+ max_weight = weight;
47
+ for (i = 0; i < n; i++) best[i] = u[i];
48
+ }
49
+ }
50
+ else if (weight <= capa) {
51
+ u[i] = 0; step(i+1, profit, weight);
52
+ u[i] = 1; step(i+1, profit + p[i], weight + w[i]);
53
+ }
54
+ }
55
+
56
+ void solve() { step(0, 0, 0); }
57
+
58
+ void output() {
59
+ cout << "item:";
60
+ for (int i = 0; i < n; i++)
61
+ if (best[i]) cout << " " << i+1;
62
+ cout << "\n" "profit = " << max_profit
63
+ << " weight = " << max_weight << "\n";
64
+ }
65
+ };
66
+
67
+ int main(int argc, char *argv[])
68
+ {
69
+ if (argc != 2) {
70
+ cout << "usage: " << argv[0] << " file_name\n";
71
+ return 1;
72
+ }
73
+ DP dp;
74
+ if (!dp.input(argv[1])) return 1;
75
+ dp.solve();
76
+ dp.output();
77
+ }
78
+ ```