Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma GCC optimize("Ofast,unroll-loops")
- #include "bits/stdc++.h"
- //#define NDEBUG
- #define F first
- #define S second
- #define vec vector
- #define pb push_back
- #define pll pair<ll, ll>
- #define all(m) m.begin(), m.end()
- #define rall(m) m.rbegin(), m.rend()
- #define uid uniform_int_distribution
- #define timeStamp() std::chrono::steady_clock::now()
- #define unify(m) sort(all(m)), m.erase(unique(all(m)), m.end());
- #define duration_micro(a) chrono::duration_cast<chrono::microseconds>(a).count()
- #define duration_milli(a) chrono::duration_cast<chrono::milliseconds>(a).count()
- #define fast cin.tie(0), cout.tie(0), cin.sync_with_stdio(0), cout.sync_with_stdio(0);
- using namespace std;
- using str = string;
- using ll = long long;
- using ld = long double;
- mt19937 rnd(timeStamp().time_since_epoch().count());
- mt19937_64 rndll(timeStamp().time_since_epoch().count());
- template<typename T, typename U> __attribute__((always_inline)) inline bool chmin(T& a, const U& b) {return (T)b < a ? a = b, 1 : 0;}
- template<typename T, typename U> bool chmax(T& a, const U& b) {return (T)b > a ? a = b, 1 : 0;}
- struct custom_hash {static uint64_t xs(uint64_t x) {x += 0x9e3779b97f4a7c15; x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; x = (x ^ (x >> 27)) * 0x94d049bb133111eb; return x ^ (x >> 31);} template<typename T> size_t operator()(T x) const {static const uint64_t C = timeStamp().time_since_epoch().count(); return xs(hash<T> {}(x) + C);}};
- template<typename K> using uset = unordered_set<K, custom_hash>;
- template<typename K, typename V> using umap = unordered_map<K, V, custom_hash>;
- template<typename T1, typename T2> ostream& operator<<(ostream& out, const pair<T1, T2>& x) {return out << x.F << ' ' << x.S;}
- template<typename T1, typename T2> istream& operator>>(istream& in, pair<T1, T2>& x) {return in >> x.F >> x.S;}
- template<typename T, size_t N> istream& operator>>(istream& in, array<T, N>& a) {for (auto &x : a) in >> x; return in;}
- template<typename T, size_t N> ostream& operator<<(ostream& out, const array<T, N>& a) {for (size_t i = 0; i < a.size(); ++i) {out << a[i]; if (i + 1 < a.size()) out << ' ';} return out;}
- template<typename T> istream& operator>>(istream& in, vector<T>& a) {for (auto& x : a) in >> x; return in;}
- template<typename T> ostream& operator<<(ostream& out, const vector<T>& a) {for (size_t i = 0; i < a.size(); ++i) {out << a[i]; if (i + 1 < a.size()) out << ' ';} return out;}
- mutex mtx;
- void common() {
- }
- const ll inf = 1ll << 48;
- class TestCase {
- int num;
- double weight = 1;
- stringstream out;
- public:
- TestCase(int num): num(num) {}
- double get_weight() const {return weight;}
- int get_number() const {return num;}
- string get_output() const {return out.str();}
- ll a; vec<ll> mm, n;
- void read_input() {
- cin >> a; mm.resize(a), n.resize(a); cin >> mm >> n;
- }
- void solve() {
- uint64_t m[6000]; for (int q = 0; q < a; ++q) m[q] = mm[q];
- vec dp(2, vec(a + 1, vec<uint64_t>()));
- for (int q = 0; q < 2; ++q) {
- for (int e = 0; e <= a; ++e) {
- dp[q][e].resize(e + 1, inf);
- }
- }
- if (n[0] == 0) dp[0][0][0] = 0;
- dp[0][1][1] = m[0];
- for (int q = 0; q + 1 < a; ++q) {
- const int qq = q & 1;
- auto& dpc = dp[qq];
- auto& dpn = dp[qq ^ 1];
- for (int e = 0; e <= q + 1; ++e) {
- fill(dpn[e].begin(), dpn[e].begin() + min(e + 1, q + 2), inf);
- }
- for (int e = n[q]; e <= q + 1; ++e) {
- for (int w = 0; w < e; ++w) {
- chmin(dpn[e][0], dpc[e][w]);
- chmin(dpn[e][w + 1], dpc[e][w] + m[q + 1]);
- }
- for (int w = e; w <= e; ++w) {
- chmin(dpn[e][0], dpc[e][w]);
- chmin(dpn[e + 1][w + 1], dpc[e][w] + m[q + 1]);
- }
- }
- }
- ll best = inf;
- for (int e = n[a - 1]; e <= a; ++e) {
- for (int w = 0; w <= e; ++w) {
- chmin(best, dp[(a - 1) & 1][e][w]);
- }
- }
- out << best;
- }
- };
- int main() {
- cin.tie(0), cout.tie(0), cin.sync_with_stdio(0), cout.sync_with_stdio(0);
- common();
- int T; cin >> T;
- vector<TestCase*> tests(T);
- double W = 0;
- for (int i = 0; i < T; ++i) {
- tests[i] = new TestCase(i);
- tests[i]->read_input();
- W += tests[i]->get_weight();
- }
- int THR = 3;
- vector<thread> threads(THR);
- cerr << "Threads = " << threads.size() << endl;
- for (auto& thr : threads) {
- static auto st = std::chrono::steady_clock::now();
- static double w = 0;
- static atomic<int> tc = 0;
- thr = thread([&]() {
- while (tc < T) {
- int cur = tc++;
- tests[cur]->solve();
- mtx.lock();
- double pw = w;
- if (w += tests[cur]->get_weight() / W; int(w * 100 + 1e-9) > int(pw * 100 + 1e-9)) {
- cerr << "Done " << w * 100 << "% in " << chrono::duration_cast<chrono::milliseconds>(std::chrono::steady_clock::now() - st).count() / 1e3 << "s" << endl;
- }
- mtx.unlock();
- }
- });
- }
- for (auto& thr : threads) thr.join();
- for (int i = 0; i < T; ++i) {
- cout << "Case #" << i + 1 << ": " << tests[i]->get_output() << '\n';
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment