結果
| 問題 |
No.31 悪のミックスジュース
|
| コンテスト | |
| ユーザー |
furon
|
| 提出日時 | 2023-06-02 14:07:35 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 11 ms / 5,000 ms |
| コード長 | 2,134 bytes |
| コンパイル時間 | 1,411 ms |
| コンパイル使用メモリ | 126,612 KB |
| 最終ジャッジ日時 | 2025-02-13 17:26:00 |
|
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 17 |
ソースコード
#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <functional>
#include <cmath>
#include <string>
#include <queue>
#include <map>
#include <bitset>
#include <set>
#include <stack>
#include <numeric>
#include <unordered_map>
#include <random>
using namespace std;
using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vl = vector<ll>;
using vvl = vector<vl>;
using vb = vector<bool>;
using vvb = vector<vb>;
using vd = vector<double>;
using vs = vector<string>;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using pdd = pair<double, double>;
using vpii = vector<pii>;
using vpll = vector<pll>;
using vpdd = vector<pdd>;
const int inf = (1 << 30) - 1;
const ll INF = 1LL << 60;
//const int MOD = 1000000007;
const int MOD = 998244353;
int main() {
int n, v;
cin >> n >> v;
vl a(n);
vi id(n);
vl sum(n + 1, 0);
for (int i = 0; i < n; i++) {
cin >> a[i];
sum[i + 1] = sum[i] + a[i];
}
// 最低1リットルずつ買うのでn>=vの時は全ての合計
ll ans = sum[n];
if (n >= v) {
cout << ans << endl;
return 0;
}
// 残りのv-nについて、どの果物まで追加で買うと最適か全探索
// idによって余りが出るのでコストパフォーマンスで比較
// それぞれの分母を掛けて整数で比較できるようにする
v -= n;
int minid = 0;
for (int i = 1; i < n; i++) {
if (sum[i + 1] * (minid + 1) < sum[minid + 1] * (i + 1)) {
minid = i;
}
}
// 残りがn*n以上になるように0からminidまでを買えるだけ買う
if (v > n * n) {
int num = (v - n * n) / (minid + 1);
v -= num * (minid + 1);
ans += num * sum[minid + 1];
}
// 残りはDPで求める
// dp[i][j] : i番目まででjリットル作る時の最小コスト
vvl dp(n + 1, vl(v + 1, INF));
dp[0][0] = 0;
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= v; j++) {
dp[i][j] = min(dp[i][j], dp[i - 1][j]);
if (j < i) continue;;
dp[i][j] = min(dp[i][j], dp[i - 1][j - i] + sum[i]);
dp[i][j] = min(dp[i][j], dp[i][j - i] + sum[i]);
}
}
cout << ans + dp[n][v] << endl;
return 0;
}
furon