답안 #687488

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
687488 2023-01-26T12:48:10 Z CDuong Collecting Stamps 3 (JOI20_ho_t3) C++17
0 / 100
60 ms 135172 KB
/*
#pragma GCC optimize("Ofast,unroll-loops")
#pragma GCC target("avx2,fma,bmi,bmi2,sse4.2,popcnt,lzcnt")
*/

#include <bits/stdc++.h>
#define taskname ""
#define all(x) x.begin(), x.end()
#define int long long
#define ll long long
#define ld long double
#define pb push_back
#define ff first
#define ss second
#define pii pair<int, int>
#define vi vector<int>
using namespace std;

const int mxN = 1e5 + 5;
const int mod = 1e9 + 7;
const int lim = 1e9;
const ll oo = 1e18;

int n, l, ans;
int dp[205][205][205][2];

void solve() {
    cin >> n >> l;
    int x[n + 1], t[n + 1];
    x[0] = t[0] = 0;
    for(int i = 1; i <= n; ++i)
        cin >> x[i];
    for(int i = 1; i <= n; ++i)
        cin >> t[i];

    auto dis = [&](int idx_1, int idx_2) {
        int tmp = abs(x[idx_1] - x[idx_2]);
        return min(tmp, l - tmp);
    };

    memset(dp, -1, sizeof dp);
    dp[0][0][0][0] = dp[0][0][0][1] = 0;
    for(int i = n; i > 0; --i) {
        for(int j = 0; j < i; ++j) {
            int tmp_1 = l - x[i], tmp_2 = x[j];
            int res = tmp_1 + tmp_2;
            if(res + tmp_1 > lim)
                dp[0][i][j][0] = -1;
            else
                dp[0][i][j][0] = res + tmp_1;
            if(res + tmp_2 > lim)
                dp[0][i][j][1] = -1;
            else
                dp[0][i][j][1] = res + tmp_2;
            // cout << 0 << " " << i << " " << j << " " << 0 << " " << dp[0][i][j][0] << endl;
            // cout << 0 << " " << i << " " << j << " " << 1 << " " << dp[0][i][j][1] << endl;
        }
    }
    // cout << endl;

    auto calc_dp = [&](int i, int st, int en, bool point) {
        int cur_dp = INT_MAX;
        if(point) {
            if(en == 0)
                return (ll)-1;
            int pre_en = (en + n) % (n + 1);
            if(dp[i][st][pre_en][point] != -1)
                cur_dp = min(cur_dp, dp[i][st][pre_en][point] + dis(pre_en, en));
            if(dp[i][st][pre_en][!point] != -1)
                cur_dp = min(cur_dp, dp[i][st][pre_en][!point] + dis(st, en));
            if(dp[i - 1][st][pre_en][point] != -1) {
                int new_time = dp[i - 1][st][pre_en][point] + dis(pre_en, en);
                if(new_time <= t[en])
                    cur_dp = min(cur_dp, new_time);
            }
            if(dp[i - 1][st][pre_en][!point] != -1) {
                int new_time = dp[i - 1][st][pre_en][!point] + dis(st, en);
                if(new_time <= t[en])
                    cur_dp = min(cur_dp, new_time);
            }
            if(cur_dp > lim)
                cur_dp = -1;
            dp[i][st][en][point] = cur_dp;
        }
        else {
            if(st == 0)
                return (ll)-1;
            int nxt_st = (st + 1) % (n + 1);
            if(dp[i][nxt_st][en][point] != -1)
                cur_dp = min(cur_dp, dp[i][nxt_st][en][point] + dis(st, nxt_st));
            if(dp[i][nxt_st][en][!point] != -1)
                cur_dp = min(cur_dp, dp[i][nxt_st][en][!point] + dis(st, en));
            if(dp[i - 1][nxt_st][en][point] != -1) {
                int new_time = dp[i - 1][nxt_st][en][point] + dis(st, nxt_st);
                if(new_time <= t[st])
                    cur_dp = min(cur_dp, new_time);
            }
            if(dp[i - 1][nxt_st][en][!point] != -1) {
                int new_time = dp[i - 1][nxt_st][en][!point] + dis(st, en);
                if(new_time <= t[st])
                    cur_dp = min(cur_dp, new_time);
            }
            if(cur_dp > lim)
                cur_dp = -1;
            dp[i][st][en][point] = cur_dp;
        }
        if(cur_dp != -1)
            return i;
        else
            return (ll)-1;
    };

    for(int i = 1; i <= n; ++i) {
        for(int len = i; len <= n; ++len) {
            for(int en = 0; en <= len; ++en) {
                int st = en - len; if(st < 0) st += n + 1;
                for(int point = 0; point <= 1; ++point) {
                    ans = max(ans, calc_dp(i, st, en, point));
                    // cout << i << " " << st << " " << en << " " << point << " " << dp[i][st][en][point] << endl;
                }
            }
        }
        // cout << endl;
    }
    cout << ans << endl;
}

signed main() {

#ifndef CDuongg
    if(fopen(taskname".inp", "r"))
        assert(freopen(taskname".inp", "r", stdin)), assert(freopen(taskname".out", "w", stdout));
#else
    freopen("bai3.inp", "r", stdin);
    freopen("bai3.out", "w", stdout);
    auto start = chrono::high_resolution_clock::now();
#endif

    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    int t = 1; //cin >> t;
    while(t--) solve();

#ifdef CDuongg
    auto end = chrono::high_resolution_clock::now();
    cout << "\n"; for(int i = 1; i <= 100; ++i) cout << '=';
    cout << "\nExecution time: " << chrono::duration_cast<chrono::milliseconds> (end - start).count() << "[ms]" << endl;
#endif

}
# 결과 실행 시간 메모리 Grader output
1 Correct 60 ms 135156 KB Output is correct
2 Correct 54 ms 135172 KB Output is correct
3 Incorrect 55 ms 135104 KB Output isn't correct
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 60 ms 135156 KB Output is correct
2 Correct 54 ms 135172 KB Output is correct
3 Incorrect 55 ms 135104 KB Output isn't correct
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 60 ms 135156 KB Output is correct
2 Correct 54 ms 135172 KB Output is correct
3 Incorrect 55 ms 135104 KB Output isn't correct
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 60 ms 135156 KB Output is correct
2 Correct 54 ms 135172 KB Output is correct
3 Incorrect 55 ms 135104 KB Output isn't correct
4 Halted 0 ms 0 KB -