提出 #14821684


ソースコード 拡げる

#include <bits/stdc++.h>
using namespace std;

mt19937 rnd;
uniform_real_distribution<> dist01(0.0, 1.0);
double rnd01(){ return dist01(rnd);}

const double TIME_LIMIT = 1950;
double elapsed;
chrono::system_clock::time_point t_start;
void update_time(){
    auto t_now = chrono::system_clock::now();
    elapsed = chrono::duration_cast<chrono::milliseconds>(t_now - t_start).count();
}
bool timeover(){ return (elapsed > TIME_LIMIT);}

const int D = 365, T = 26;
int C[T], S[D][T];
int CS[D+2][T];

vector<int> st[T];

int ans[D];
int opt = -1e9;

int calc_score(){
    int last[T];
    for(int i=0; i<T; i++) last[i] = -1;
    int res = 0;
    for(int i=0; i<D; i++){
        res += S[i][ans[i]];
        last[ans[i]] = i;
        for(int j=0; j<T; j++) res -= C[j] * (i-last[j]);
    }
    return res;
}

int calc_diff(int t, int bef, int aft){
    int res = opt + S[t][aft] - S[t][bef];
    {
        auto it = lower_bound(st[bef].begin(), st[bef].end(), t);
        int d1 = *next(it) - t, d2 = t - *prev(it);
        res -= CS[d1+d2][bef] - CS[d1][bef] - CS[d2][bef];
    }
    {
        auto it = lower_bound(st[aft].begin(), st[aft].end(), t);
        int d1 = *it - t, d2 = t - *prev(it);
        res += CS[d1+d2][aft] - CS[d1][aft] - CS[d2][aft];
    }
    return res;
}

int calc_swap(int t, int bef, int aft){
    int res = opt + S[t][aft] - S[t][bef] - S[t+1][aft] + S[t+1][bef];
    {
        auto it = lower_bound(st[bef].begin(), st[bef].end(), t);
        int d1 = *next(it) - t, d2 = t - *prev(it);
        res -= CS[d1-1][bef] + CS[d2+1][bef] - CS[d1][bef] - CS[d2][bef];
    }
    {
        auto it = lower_bound(st[aft].begin(), st[aft].end(), t+1);
        int d1 = *next(it) - t, d2 = t - *prev(it);
        res += CS[d1-1][aft] + CS[d2+1][aft] - CS[d1][aft] - CS[d2][aft];
    }
    return res;
}

int update_cnt = 0;

void try_update(){
    // pick random & update
    int t = rnd() % D;
    int bef = ans[t], aft = rnd() % T;
    if(bef == aft) return;

    // calculate
    int score = calc_diff(t, bef, aft);
    const int T = 4000;
    double temp = T * (1 - elapsed/TIME_LIMIT);
    double prob = exp((score - opt) / temp);
    if(rnd01() < prob){
        opt = score;
        ans[t] = aft;
        st[aft].insert(lower_bound(st[aft].begin(), st[aft].end(), t), t);
        st[bef].erase(lower_bound(st[bef].begin(), st[bef].end(), t));
        update_cnt++;
    }else{
        // rollback
    }
}

void try_swap(){
    // pick random & update
    int t = rnd() % (D-1);
    int bef = ans[t], aft = ans[t+1];
    if(bef == aft) return;

    // calculate
    int score = calc_swap(t, bef, aft);
    const int Temp = 4000;
    double temp = Temp * (1 - elapsed/TIME_LIMIT);
    double prob = exp((score - opt) / temp);
    if(rnd01() < prob){
        opt = score;
        swap(ans[t], ans[t+1]);
        (*lower_bound(st[aft].begin(), st[aft].end(), t))--;
        (*lower_bound(st[bef].begin(), st[bef].end(), t))++;
        update_cnt++;
    }else{
        // rollback
    }
}

int main(){
    t_start = chrono::system_clock::now();
    // get input & initialize
    int _; cin >> _;
    for(int j=0; j<T; j++) cin >> C[j];
    for(int i=0; i<D; i++) for(int j=0; j<T; j++) cin >> S[i][j];
    for(int i=0; i<=D+1; i++) for(int j=0; j<T; j++) CS[i][j] = i*(i-1)/2*C[j];

    for(int i=0; i<D; i++) for(int j=0; j<T; j++) if(S[i][ans[i]] < S[i][j]) ans[i] = j;
    opt = calc_score();
    cerr << "before score: " << opt << endl;

    for(int j=0; j<T; j++) st[j].push_back(-1);
    for(int i=0; i<D; i++) st[ans[i]].push_back(i);
    for(int j=0; j<T; j++) st[j].push_back(D);

    // iterate
    int iter = 0;
    while(!timeover()){
        iter++;
        try_update();
        if(iter%10 == 0) try_swap();
        if(iter % 100000 == 0) update_time();
    }

    // output result
    for(int i=0; i<D; i++) cout << ans[i]+1 << endl;


    // output debug
    cerr << "score: " << opt << endl;
    cerr << "iter: " << iter << endl;
    update_time();
    cerr << "elapsed: " << elapsed << endl;
    cerr << "update count: " << update_cnt << endl;
    return 0;
}

提出情報

提出日時
問題 A - AtCoder Contest Scheduling
ユーザ betrue12
言語 C++ (GCC 9.2.1)
得点 120718852
コード長 4245 Byte
結果 AC
実行時間 1970 ms
メモリ 4512 KiB

ジャッジ結果

セット名 test_ALL
得点 / 配点 120718852 / 365000000
結果
AC × 50
セット名 テストケース
test_ALL test_00.txt, test_01.txt, test_02.txt, test_03.txt, test_04.txt, test_05.txt, test_06.txt, test_07.txt, test_08.txt, test_09.txt, test_10.txt, test_11.txt, test_12.txt, test_13.txt, test_14.txt, test_15.txt, test_16.txt, test_17.txt, test_18.txt, test_19.txt, test_20.txt, test_21.txt, test_22.txt, test_23.txt, test_24.txt, test_25.txt, test_26.txt, test_27.txt, test_28.txt, test_29.txt, test_30.txt, test_31.txt, test_32.txt, test_33.txt, test_34.txt, test_35.txt, test_36.txt, test_37.txt, test_38.txt, test_39.txt, test_40.txt, test_41.txt, test_42.txt, test_43.txt, test_44.txt, test_45.txt, test_46.txt, test_47.txt, test_48.txt, test_49.txt
ケース名 結果 実行時間 メモリ
test_00.txt AC 1961 ms 4512 KiB
test_01.txt AC 1961 ms 4344 KiB
test_02.txt AC 1957 ms 4284 KiB
test_03.txt AC 1963 ms 4272 KiB
test_04.txt AC 1963 ms 4284 KiB
test_05.txt AC 1966 ms 4288 KiB
test_06.txt AC 1966 ms 4292 KiB
test_07.txt AC 1960 ms 4364 KiB
test_08.txt AC 1964 ms 4284 KiB
test_09.txt AC 1964 ms 4300 KiB
test_10.txt AC 1956 ms 4308 KiB
test_11.txt AC 1959 ms 4300 KiB
test_12.txt AC 1962 ms 4364 KiB
test_13.txt AC 1962 ms 4300 KiB
test_14.txt AC 1955 ms 4292 KiB
test_15.txt AC 1962 ms 4356 KiB
test_16.txt AC 1957 ms 4340 KiB
test_17.txt AC 1955 ms 4356 KiB
test_18.txt AC 1970 ms 4376 KiB
test_19.txt AC 1965 ms 4304 KiB
test_20.txt AC 1955 ms 4368 KiB
test_21.txt AC 1961 ms 4300 KiB
test_22.txt AC 1957 ms 4288 KiB
test_23.txt AC 1961 ms 4328 KiB
test_24.txt AC 1962 ms 4340 KiB
test_25.txt AC 1957 ms 4380 KiB
test_26.txt AC 1968 ms 4364 KiB
test_27.txt AC 1956 ms 4304 KiB
test_28.txt AC 1958 ms 4300 KiB
test_29.txt AC 1964 ms 4344 KiB
test_30.txt AC 1955 ms 4472 KiB
test_31.txt AC 1962 ms 4324 KiB
test_32.txt AC 1963 ms 4328 KiB
test_33.txt AC 1956 ms 4300 KiB
test_34.txt AC 1955 ms 4312 KiB
test_35.txt AC 1960 ms 4356 KiB
test_36.txt AC 1957 ms 4312 KiB
test_37.txt AC 1963 ms 4304 KiB
test_38.txt AC 1960 ms 4476 KiB
test_39.txt AC 1958 ms 4356 KiB
test_40.txt AC 1955 ms 4476 KiB
test_41.txt AC 1961 ms 4476 KiB
test_42.txt AC 1958 ms 4420 KiB
test_43.txt AC 1964 ms 4296 KiB
test_44.txt AC 1957 ms 4272 KiB
test_45.txt AC 1957 ms 4328 KiB
test_46.txt AC 1962 ms 4368 KiB
test_47.txt AC 1965 ms 4272 KiB
test_48.txt AC 1965 ms 4380 KiB
test_49.txt AC 1966 ms 4296 KiB