結果
| 問題 | No.3401 Large Knapsack Problem |
| コンテスト | |
| ユーザー |
apricity
|
| 提出日時 | 2025-12-09 02:18:34 |
| 言語 | C++23 (gcc 13.3.0 + boost 1.89.0) |
| 結果 |
AC
|
| 実行時間 | 41 ms / 2,000 ms |
| コード長 | 6,982 bytes |
| 記録 | |
| コンパイル時間 | 3,867 ms |
| コンパイル使用メモリ | 249,016 KB |
| 実行使用メモリ | 7,848 KB |
| 最終ジャッジ日時 | 2025-12-09 02:18:41 |
| 合計ジャッジ時間 | 6,808 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 42 |
コンパイルメッセージ
main.cpp: In function ‘void fastio::flush()’:
main.cpp:70:21: warning: ignoring return value of ‘ssize_t write(int, const void*, size_t)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
70 | void flush() { write(1, obuf, obufi), obufi = 0; }
| ~~~~~^~~~~~~~~~~~~~~~
ソースコード
#pragma GCC target("prefer-vector-width=512")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("Ofast,unroll-loops")
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<numeric>
#include<cmath>
#include<utility>
#include<tuple>
#include<array>
#include<cstdint>
#include<cstdio>
#include<iomanip>
#include<map>
#include<set>
#include<unordered_map>
#include<unordered_set>
#include<queue>
#include<stack>
#include<deque>
#include<bitset>
#include<cctype>
#include<chrono>
#include<random>
#include<cassert>
#include<cstddef>
#include<iterator>
#include<string_view>
#include<type_traits>
#include<functional>
using namespace std;
#include <cstring>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
namespace fastio {
#ifndef FAST_IO
#define FAST_IO
#endif
struct Pre {
char num[10000][4];
constexpr Pre() : num() {
for (int i = 0; i < 10000; i++) {
int n = i;
for (int j = 3; j >= 0; j--) {
num[i][j] = n % 10 | '0';
n /= 10;
}
}
}
} constexpr pre;
static constexpr int BUF_SZ = 1 << 18;
char *ibuf, obuf[BUF_SZ], outs[100];
int outi, obufi;
void __attribute__((constructor)) _c() {
struct stat sb;
fstat(0, &sb);
ibuf = (char *)mmap(0, sb.st_size, PROT_READ, MAP_SHARED /*| MAP_POPULATE*/, 0, 0);
}
void flush() { write(1, obuf, obufi), obufi = 0; }
void input(char &c) { c = *ibuf++; }
void input(string &x) {
x.clear();
char c;
do { input(c); } while (isspace(c));
do { x += c, input(c); } while (!isspace(c));
}
template <typename T>
void input_integer(T &x) {
char c;
do { input(c); } while (c < '-');
bool minus = 0;
if constexpr (is_signed<T>::value || is_same_v<T, __int128>) {
if (c == '-') { minus = 1, input(c); }
}
x = 0;
while (c >= '0') { x = x * 10 + (c & 15), input(c); }
if constexpr (is_signed<T>::value || is_same_v<T, __int128>) {
if (minus) { x = -x; }
}
}
template <typename T>
void input_real(T &x) { string s; input(s); x = stod(s); }
void input(int &x) { input_integer(x); }
void input(long long &x) { input_integer(x); }
void input(__int128 &x) { input_integer(x); }
void input(uint32_t &x) { input_integer(x); }
void input(uint64_t &x) { input_integer(x); }
void input(unsigned __int128 &x) { input_integer(x); }
void input(double &x) { input_real(x); }
template <class T>
void input(vector<T> &x) { for (auto &d : x) input(d); }
template <typename T, size_t N = 0>
void input(array<T, N> &x) { for (auto &d : x) input(d); }
template <class T, class U>
void input(pair<T, U> &p) { input(p.first), input(p.second); }
template <size_t N = 0, typename T>
void input_tuple(T &t) {
if constexpr (N < std::tuple_size<T>::value) {
auto &x = std::get<N>(t);
input(x);
input_tuple<N + 1>(t);
}
}
template <class... T>
void input(tuple<T...> &tpl) { input_tuple(tpl); }
void in() {}
template <class H, class... T>
void in(H &h, T &... t) { input(h), in(t...); }
void output(const char c) {
if (obufi == BUF_SZ) flush();
obuf[obufi++] = c;
}
void output(const string &s) { for (char c : s) output(c); }
template <typename T>
void output_integer(T x) {
if (obufi > BUF_SZ - 100) flush();
if (x < 0) { obuf[obufi++] = '-', x = -x; }
for (outi = 96; x >= 10000; outi -= 4) {
memcpy(outs + outi, pre.num[x % 10000], 4);
x /= 10000;
}
if (x >= 1000) {
memcpy(obuf + obufi, pre.num[x], 4);
obufi += 4;
}
else if (x >= 100) {
memcpy(obuf + obufi, pre.num[x] + 1, 3);
obufi += 3;
}
else if(x >= 10) {
int q = (x * 103) >> 10;
obuf[obufi] = q | '0';
obuf[obufi + 1] = (x - q * 10) | '0';
obufi += 2;
}
else {
obuf[obufi++] = x | '0';
}
memcpy(obuf + obufi, outs + outi + 4, 96 - outi);
obufi += 96 - outi;
}
template <typename T>
void output_real(T x) {
ostringstream oss;
oss << fixed << setprecision(15) << double(x);
string s = oss.str();
output(s);
}
void output(int x) { output_integer(x); }
void output(long long x) { output_integer(x); }
void output(__int128 x) { output_integer(x); }
void output(uint32_t x) { output_integer(x); }
void output(uint64_t x) { output_integer(x); }
void output(unsigned __int128 x) { output_integer(x); }
void output(double x) { output_real(x); }
void output(long double x) { output_real(x); }
template <class T>
void output(const vector<T> &val) {
size_t n = val.size();
for (size_t i = 0; i < n; i++) {
if (i) output(' ');
output(val[i]);
}
}
template <class T, class U>
void output(const pair<T, U> &val) {
output(val.first); output(' '); output(val.second);
}
template <size_t N = 0, typename T>
void output_tuple(const T &t) {
if constexpr (N < std::tuple_size<T>::value) {
if constexpr (N > 0) { output(' '); }
const auto x = std::get<N>(t);
output(x);
output_tuple<N+1>(t);
}
}
template <class... T>
void output(tuple<T...> &tpl) { output_tuple(tpl); }
template <class T, size_t N>
void output(const array<T, N> &val) {
size_t n = val.size();
for (size_t i = 0; i < n; i++) {
if (i) output(' ');
output(val[i]);
}
}
void out() { output('\n'); }
template <class H, class... T, char sep = ' '>
void out(H &&h, T &&... t) {
output(h);
if (sizeof...(T)) output(sep);
out(t...);
}
void outr() {}
template <class H, class... T>
void outr(H &&h, T &&... t) {
output(h);
outr(t...);
}
void __attribute__((destructor)) _d() { flush(); }
} // namespace fastio
using fastio::in;
using fastio::out;
using ll = long long;
constexpr ll INF = 1e18;
int coef[1000], vi[20], wi[20];
ll dp[1000], f[1000], aux1[1000], aux2[1000];
int main() {
int n, m; in(n, m);
for (int i = 0; i < n; i++) {
in(vi[i], wi[i]);
coef[1000 - wi[i]] = max(coef[1000 - wi[i]], vi[i]);
}
for (int x = 1; x < 1000; x++) {
for (int i = 0; i < n; i++) {
if (x >= wi[i]) dp[x] = max(dp[x], dp[x - wi[i]] + vi[i]);
}
}
fill_n(f, 1000, -INF);
f[0] = 0;
int p = 31 - __builtin_clz(m);
while (p >= 0) {
memcpy(aux1, f, sizeof(ll) * 1000);
memcpy(aux2, f, sizeof(ll) * 1000);
for (int i = 0; i < 1000; i++) f[i] = aux1[0] + aux2[i];
for (int i = 1; i < 1000; i++) {
ll bk = aux2[999];
for (int j = 999; j >= 1; j--) aux2[j] = max(aux2[j - 1], bk + coef[j]);
aux2[0] = bk + coef[0];
for (int j = 0; j < 1000; j++) f[j] = max(f[j], aux1[i] + aux2[j]);
}
if (m >> p & 1) {
ll bk = f[999];
for (int i = 999; i >= 1; i--) f[i] = max(f[i - 1], bk + coef[i]);
f[0] = bk + coef[0];
}
p--;
}
ll ans = 0;
for (int i = 0; i < 1000; i++) ans = max(ans, f[i] + dp[i]);
out(ans);
}
apricity