結果
問題 | No.2617 容量3のナップザック |
ユーザー | startcpp |
提出日時 | 2022-02-05 19:26:45 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 182 ms / 2,000 ms |
コード長 | 4,354 bytes |
コンパイル時間 | 1,153 ms |
コンパイル使用メモリ | 94,020 KB |
実行使用メモリ | 61,568 KB |
最終ジャッジ日時 | 2024-09-27 11:10:45 |
合計ジャッジ時間 | 5,859 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
6,812 KB |
testcase_01 | AC | 2 ms
6,940 KB |
testcase_02 | AC | 1 ms
6,944 KB |
testcase_03 | AC | 1 ms
6,940 KB |
testcase_04 | AC | 2 ms
6,940 KB |
testcase_05 | AC | 2 ms
6,940 KB |
testcase_06 | AC | 2 ms
6,940 KB |
testcase_07 | AC | 2 ms
6,944 KB |
testcase_08 | AC | 2 ms
6,940 KB |
testcase_09 | AC | 2 ms
6,940 KB |
testcase_10 | AC | 2 ms
6,944 KB |
testcase_11 | AC | 2 ms
6,940 KB |
testcase_12 | AC | 133 ms
44,448 KB |
testcase_13 | AC | 129 ms
54,148 KB |
testcase_14 | AC | 129 ms
42,860 KB |
testcase_15 | AC | 90 ms
35,488 KB |
testcase_16 | AC | 92 ms
32,348 KB |
testcase_17 | AC | 123 ms
41,188 KB |
testcase_18 | AC | 113 ms
41,528 KB |
testcase_19 | AC | 19 ms
9,848 KB |
testcase_20 | AC | 118 ms
49,448 KB |
testcase_21 | AC | 67 ms
23,596 KB |
testcase_22 | AC | 136 ms
55,144 KB |
testcase_23 | AC | 155 ms
53,796 KB |
testcase_24 | AC | 9 ms
6,944 KB |
testcase_25 | AC | 78 ms
33,436 KB |
testcase_26 | AC | 98 ms
34,072 KB |
testcase_27 | AC | 53 ms
19,696 KB |
testcase_28 | AC | 7 ms
6,940 KB |
testcase_29 | AC | 50 ms
22,172 KB |
testcase_30 | AC | 133 ms
50,596 KB |
testcase_31 | AC | 126 ms
40,404 KB |
testcase_32 | AC | 153 ms
59,328 KB |
testcase_33 | AC | 172 ms
58,972 KB |
testcase_34 | AC | 174 ms
59,508 KB |
testcase_35 | AC | 162 ms
59,052 KB |
testcase_36 | AC | 180 ms
58,604 KB |
testcase_37 | AC | 182 ms
61,568 KB |
testcase_38 | AC | 153 ms
59,220 KB |
testcase_39 | AC | 145 ms
58,036 KB |
testcase_40 | AC | 167 ms
61,124 KB |
testcase_41 | AC | 83 ms
58,224 KB |
ソースコード
#include <iostream> #include <algorithm> #include <cstdio> #include <random> #include <cassert> #define int long long using namespace std; mt19937 mt(7623765); class TestCase { public: int N, K, seed, a, b, m; vector<int> f, w, v; vector<int> values[4]; //values[weight] = 価値リスト private: bool is_valid() { if (N <= 0 || N > 1000000) return false; if (K <= 0 || K > N) return false; if (m <= 2 || m > 1000000000) return false; if (a <= 0 || a >= m) return false; if (b <= 0 || b >= m) return false; if (seed <= 0 || seed >= m) return false; return true; } void generate_fwv() { f.resize(2 * N); f[0] = seed; for (int i = 1; i < 2 * N; i++) { f[i] = (a * f[i - 1] + b) % m; } w.resize(N); for (int i = 0; i < N; i++) { w[i] = f[i] % 3 + 1; } v.resize(N); for (int i = 0; i < N; i++) { v[i] = w[i] * f[N + i]; } } void generate_values() { for (int i = 0; i < N; i++) { values[w[i]].push_back(v[i]); } } public: void input() { cin >> N >> K >> seed >> a >> b >> m; assert(is_valid()); generate_fwv(); generate_values(); } void generate(int N) { this->N = N; K = mt() % N + 1; m = mt() % 999999998 + 3; a = mt() % (m - 1) + 1; b = mt() % (m - 1) + 1; seed = mt() % (m - 1) + 1; assert(is_valid()); generate_fwv(); generate_values(); } void print() { printf("N = %lld, K = %lld, seed = %lld, a = %lld, b = %lld, m = %lld\n", N, K, seed, a, b, m); for (int i = 1; i <= 3; i++) { for (int j = 0; j < values[i].size(); j++) { cout << values[i][j]; if (j + 1 < values[i].size()) cout << " "; } cout << endl; } } }; class Solver { protected: int N, K; vector<int> values[4]; void input(TestCase &testcase) { N = testcase.N; K = testcase.K; for (int i = 0; i < 4; i++) { values[i] = testcase.values[i]; } } public: virtual int solve(TestCase &testcase) = 0; }; class NaiveSolver : public Solver { public: int solve(TestCase &testcase) { input(testcase); for (int i = 1; i <= 3; i++) { sort(values[i].begin(), values[i].end(), greater<int>()); } vector<int> sum_values[4]; //sum_values[weight][count] = 重さ合計 for (int i = 1; i <= 3; i++) { sum_values[i].resize(values[i].size() + 1); sum_values[i][0] = 0; for (int j = 0; j < values[i].size(); j++) { sum_values[i][j + 1] = sum_values[i][j] + values[i][j]; } } int ans = 0; for (int i = 0; i <= values[1].size(); i++) { for (int j = 0; j <= values[2].size(); j++) { for (int k = 0; k <= values[3].size(); k++) { int box_count = k + j + (max(0LL, i - j) + 2) / 3; if (box_count <= K) { ans = max(ans, sum_values[1][i] + sum_values[2][j] + sum_values[3][k]); } } } } return ans; } }; class FastSolver : public Solver { vector<int> sum_values[4]; int sum_values_func(int weight, int cnt) { if (cnt < sum_values[weight].size()) { return sum_values[weight][cnt]; } return sum_values[weight][values[weight].size()]; } //重さ2をx個使うとしたとき、重さ1, 2の荷物を容量3のナップザックに詰めるときの価値和のmaxは? int f(int x, int i) { return sum_values[2][i] + sum_values_func(1, 3 * x - 2 * i); } //重さ1, 2の荷物を、容量3のナップザックx個に詰めるときの、詰める荷物の価値和の最大値 int f(int x) { //f(x, i + 1) - f(x, i) <= 0になる最小のiは?0 <= i < c_2, 無ければc_2. int c_2 = min(x, (int)values[2].size()); int ng = -1, ok = c_2, mid; //(ng, ok] while (ok - ng >= 2) { mid = (ng + ok) / 2; if (f(x, mid + 1) - f(x, mid) <= 0) { ok = mid; } else { ng = mid; } } return f(x, ok); } public: int solve(TestCase &testcase) { input(testcase); for (int i = 1; i <= 3; i++) { sort(values[i].begin(), values[i].end(), greater<int>()); sum_values[i].resize(values[i].size() + 1); sum_values[i][0] = 0; for (int j = 0; j < values[i].size(); j++) { sum_values[i][j + 1] = sum_values[i][j] + values[i][j]; } } int ans = 0; for (int i = 0; i <= min(K, (int)values[3].size()); i++) { //重さ3をi個使う int res = sum_values[3][i] + f(K - i); ans = max(ans, res); } return ans; } }; FastSolver fast; signed main() { TestCase test; test.input(); cout << fast.solve(test) << endl; return 0; }