結果
| 問題 | No.3683 サーバー代がもったいない! |
| コンテスト | |
| ユーザー |
drken1215
|
| 提出日時 | 2026-07-15 14:26:15 |
| 言語 | C++23 (gcc 15.3.0 + boost 1.92.0 + ACL) |
| 結果 |
AC
不安定
|
| 実行時間 | 179 ms / 2,000 ms |
| + 447µs | |
| コード長 | 9,878 bytes |
| 記録 | |
| コンパイル時間 | 2,410 ms |
| コンパイル使用メモリ | 363,320 KB |
| 実行使用メモリ | 6,272 KB |
| 最終ジャッジ日時 | 2026-09-05 12:40:58 |
| 合計ジャッジ時間 | 7,359 ms |
|
ジャッジサーバーID (参考情報) |
judge2_0 / judge3_0 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 27 |
ソースコード
// code template is in https://github.com/drken1215/algorithm/blob/master/template_minimum.cpp
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
using namespace std;
//------------------------------//
// Utility
//------------------------------//
using ll = long long;
using i128 = __int128_t;
using u128 = __uint128_t;
using pint = pair<int, int>;
using pll = pair<long long, long long>;
using tll = array<long long, 3>;
using fll = array<long long, 4>;
using vint = vector<int>;
using vll = vector<long long>;
using dint = deque<int>;
using dll = deque<long long>;
using vvint = vector<vector<int>>;
using vvll = vector<vector<long long>>;
using vpll = vector<pair<long long, long long>>;
template<class T> using min_priority_queue = priority_queue<T, vector<T>, greater<T>>;
template<class S, class T> inline bool chmax(S &a, T b) { return (a < b ? a = b, 1 : 0); }
template<class S, class T> inline bool chmin(S &a, T b) { return (a > b ? a = b, 1 : 0); }
template<class S, class T> inline auto maxll(S a, T b) { return max(ll(a), ll(b)); }
template<class S, class T> inline auto minll(S a, T b) { return min(ll(a), ll(b)); }
template<class T> auto max(const T &a) { return *max_element(a.begin(), a.end()); }
template<class T> auto min(const T &a) { return *min_element(a.begin(), a.end()); }
template<class T> auto argmax(const T &a) { return max_element(a.begin(), a.end()) - a.begin(); }
template<class T> auto argmin(const T &a) { return min_element(a.begin(), a.end()) - a.begin(); }
template<class T> auto accum(const vector<T> &a) { return accumulate(a.begin(), a.end(), T()); }
template<class T> auto accum(const deque<T> &a) { return accumulate(a.begin(), a.end(), T()); }
#define REP(i, a) for (long long i = 0; i < (long long)(a); i++)
#define REP2(i, a, b) for (long long i = a; i < (long long)(b); i++)
#define RREP(i, a) for (long long i = (a)-1; i >= (long long)(0); --i)
#define RREP2(i, a, b) for (long long i = (b)-1; i >= (long long)(a); --i)
#define EB emplace_back
#define PF push_front
#define PB push_back
#define MP make_pair
#define FI first
#define SE second
#define ALL(x) x.begin(), x.end()
#define COUT(x) cout << #x << " = " << (x) << " (L" << __LINE__ << ")" << endl
// input
template<class T> istream& operator >> (istream &is, vector<T> &P)
{ for (int i = 0; i < (int)P.size(); ++i) cin >> P[i]; return is; }
template<class T> istream& operator >> (istream &is, deque<T> &P)
{ for (int i = 0; i < (int)P.size(); ++i) cin >> P[i]; return is; }
template<class T> istream& operator >> (istream &is, vector<vector<T>> &P)
{ for (int i = 0; i < (int)P.size(); ++i) cin >> P[i]; return is; }
// output
template<class S, class T> ostream& operator << (ostream &s, const pair<S, T> &P)
{ return s << '<' << P.first << ", " << P.second << '>'; }
template<class T> ostream& operator << (ostream &s, const array<T, 2> &P)
{ return s << '<' << P[0] << "," << P[1] << '>'; }
template<class T> ostream& operator << (ostream &s, const array<T, 3> &P)
{ return s << '<' << P[0] << "," << P[1] << "," << P[2] << '>'; }
template<class T> ostream& operator << (ostream &s, const array<T, 4> &P)
{ return s << '<' << P[0] << "," << P[1] << "," << P[2] << "," << P[3] << '>'; }
template<class T> ostream& operator << (ostream &s, const vector<T> &P)
{ for (int i = 0; i < P.size(); ++i) { if (i > 0) { s << " "; } s << P[i]; } return s; }
template<class T> ostream& operator << (ostream &s, const deque<T> &P)
{ for (int i = 0; i < P.size(); ++i) { if (i > 0) { s << " "; } s << P[i]; } return s; }
template<class T> ostream& operator << (ostream &s, const vector<vector<T>> &P)
{ for (int i = 0; i < P.size(); ++i) { s << endl << P[i]; } return s << endl; }
template<class T> ostream& operator << (ostream &s, const set<T> &P)
{ for (auto it : P) { s << "<" << it << "> "; } return s; }
template<class T> ostream& operator << (ostream &s, const multiset<T> &P)
{ for (auto it : P) { s << "<" << it << "> "; } return s; }
template<class T> ostream& operator << (ostream &s, const unordered_set<T> &P)
{ for (auto it : P) { s << "<" << it << "> "; } return s; }
template<class S, class T> ostream& operator << (ostream &s, const map<S, T> &P)
{ for (auto it : P) { s << "<" << it.first << "->" << it.second << "> "; } return s; }
template<class S, class T> ostream& operator << (ostream &s, const unordered_map<S, T> &P)
{ for (auto it : P) { s << "<" << it.first << "->" << it.second << "> "; } return s; }
void yes(bool a) { cout << (a ? "yes" : "no") << endl; }
void YES(bool a) { cout << (a ? "YES" : "NO") << endl; }
void Yes(bool a) { cout << (a ? "Yes" : "No") << endl; }
const vector<int> DX = {1, 0, -1, 0, 1, -1, 1, -1};
const vector<int> DY = {0, 1, 0, -1, 1, -1, -1, 1};
// Segment Tree
template<class Monoid> struct SegmentTree {
using Func = function<Monoid(Monoid, Monoid)>;
// core member
int N;
Func OP;
Monoid IDENTITY;
// inner data
int log, offset;
vector<Monoid> dat;
// constructor
SegmentTree() {}
SegmentTree(const Func &op, const Monoid &identity) : OP(op), IDENTITY(identity) { }
SegmentTree(int n, const Func &op, const Monoid &identity) {
init(n, op, identity);
}
SegmentTree(const vector<Monoid> &v, const Func &op, const Monoid &identity) {
init(v, op, identity);
}
void init(const Func &op, const Monoid &identity) {
OP = op;
IDENTITY = identity;
}
void init(int n) {
N = n;
log = 0, offset = 1;
while (offset < N) ++log, offset <<= 1;
dat.assign(offset * 2, IDENTITY);
}
void init(const vector<Monoid> &v) {
init((int)v.size());
build(v);
}
void init(int n, const Func &op, const Monoid &identity) {
init(op, identity);
init(n);
}
void init(const vector<Monoid> &v, const Func &op, const Monoid &identity) {
init((int)v.size(), op, identity);
build(v);
}
int size() const {
return N;
}
// pull, build
void pull(int k) {
dat[k] = OP(dat[k * 2], dat[k * 2 + 1]);
}
void build(const vector<Monoid> &v) {
assert(N == (int)v.size());
for (int i = 0; i < N; ++i) dat[i + offset] = v[i];
for (int k = offset - 1; k > 0; --k) pull(k);
}
// setter and getter, set: update A[i], i is 0-indexed, O(log N)
void set(int i, const Monoid &v) {
assert(0 <= i && i < N);
int k = i + offset;
dat[k] = v;
while (k >>= 1) pull(k);
}
Monoid get(int i) const {
assert(0 <= i && i < N);
return dat[i + offset];
}
Monoid operator [] (int i) const {
return get(i);
}
// get [l, r), l and r are 0-indexed, O(log N)
Monoid prod(int l, int r) {
assert(0 <= l && l <= r && r <= N);
Monoid val_left = IDENTITY, val_right = IDENTITY;
l += offset, r += offset;
for (; l < r; l >>= 1, r >>= 1) {
if (l & 1) val_left = OP(val_left, dat[l++]);
if (r & 1) val_right = OP(dat[--r], val_right);
}
return OP(val_left, val_right);
}
Monoid all_prod() {
return dat[1];
}
// get max r that f(get(l, r)) = True (0-indexed), O(log N)
// f(IDENTITY) need to be True
int max_right(const function<bool(Monoid)> f, int l = 0) {
if (l == N) return N;
l += offset;
Monoid sum = IDENTITY;
do {
while (l % 2 == 0) l >>= 1;
if (!f(OP(sum, dat[l]))) {
while (l < offset) {
l = l * 2;
if (f(OP(sum, dat[l]))) {
sum = OP(sum, dat[l]);
++l;
}
}
return l - offset;
}
sum = OP(sum, dat[l]);
++l;
} while ((l & -l) != l); // stop if l = 2^e
return N;
}
// get min l that f(get(l, r)) = True (0-indexed), O(log N)
// f(IDENTITY) need to be True
int min_left(const function<bool(Monoid)> f, int r = -1) {
if (r == 0) return 0;
if (r == -1) r = N;
r += offset;
Monoid sum = IDENTITY;
do {
--r;
while (r > 1 && (r % 2)) r >>= 1;
if (!f(OP(dat[r], sum))) {
while (r < offset) {
r = r * 2 + 1;
if (f(OP(dat[r], sum))) {
sum = OP(dat[r], sum);
--r;
}
}
return r + 1 - offset;
}
sum = OP(dat[r], sum);
} while ((r & -r) != r);
return 0;
}
// debug
friend ostream& operator << (ostream &s, const SegmentTree &seg) {
for (int i = 0; i < (int)seg.size(); ++i) {
s << seg[i];
if (i != (int)seg.size() - 1) s << " ";
}
return s;
}
// dump
void dump() {
int pt = 1;
for (int h = 0; h <= log; h++) {
for (int i = 0; i < (1<<h); i++) cout << dat[pt++] << " ";
cout << endl;
}
}
};
//------------------------------//
// Solver
//------------------------------//
int main() {
ll N, K, INF = 1LL << 50;
cin >> N >> K;
vll A(N);
cin >> A;
ll all = accum(A);
vvll dp(K+1, vll(2, -INF)); // 0: とってない、1: とった
dp[0][0] = 0;
REP(i, N) {
vvll nex(K+1, vll(2, -INF));
REP(k, K+1) {
// 0, 1 -> 0
chmax(nex[k][0], max(dp[k][0], dp[k][1]));
// 0 -> 1
if (k+1 <= K) chmax(nex[k+1][1], dp[k][0] + A[i]);
}
swap(dp, nex);
}
ll res = max(dp[K][0], dp[K][1]);
if (res > - INF/2) cout << res << endl;
else cout << "Impossible" << endl;
}
drken1215