제출 #1355733

#제출 시각아이디문제언어결과실행 시간메모리
1355733alexddChorus (JOI23_chorus)C++20
0 / 100
0 ms344 KiB
#include <bits/stdc++.h>
using namespace std;

#define int long long

const int INF = 1e18;
const int MAXN = 5e3 + 5;

int n,k;
string s;
int pozb[MAXN];



typedef long long ld;

pair<ld, pair<int,int>> solve(ld coef)//{{rez_coef, {nr_swaps, cnt_songs}}
{
    vector<ld> dp(n+2);
    vector<int> real_dp(n+2), cnt_songs(n+2);

    vector<int> pref(n+2,0);

    dp[0] = 0;
    real_dp[0] = 0;
    cnt_songs[0] = 0;
    for(int i=1;i<=n;i++)
    {
        dp[i] = INF;
        real_dp[i] = INF;
        cnt_songs[i] = -1;

        int aux = 0;
        for(int old=i-1;old>=0;old--)
        {
            aux += max(0LL, i - pozb[old + 1]);

            if(real_dp[old] >= INF)
                continue;

            ld cv = dp[old] + aux + coef;
            if(cv < dp[i])
            {
                dp[i] = cv;
                real_dp[i] = real_dp[old] + aux;
                cnt_songs[i] = cnt_songs[old] + 1;
            }
        }
    }

    return {dp[n], {real_dp[n], cnt_songs[n]}};
}

void easy_dp()
{
    vector<vector<int>> dp(n+2, vector<int>(k+2,INF));
    vector<int> pref(n+2,0);
    for(int i=0;i<=n;i++)
        for(int cnt=0;cnt<=k;cnt++)
            dp[i][cnt] = INF;
    dp[0][0] = 0;
    for(int i=1;i<=n;i++)
    {
        pref[0] = 0;
        for(int u=1;u<=n;u++)
            pref[u] = pref[u-1] + max(0LL, i - pozb[u]);
        for(int cnt=1;cnt<=k;cnt++)
        {
            int mnm = INF;
            for(int old=0;old<i;old++)
                mnm = min(mnm, dp[old][cnt-1] - pref[old]);
            dp[i][cnt] = min(INF, mnm + pref[i]);
        }
    }
    cout<<dp[n][k];
}

signed main()
{
    ios_base::sync_with_stdio(0);cin.tie(0);
    cin>>n>>k>>s;
    assert(s.size() == 2 * n);
    int cnta = 0, cntb = 0;
    for(int i=0;i<2*n;i++)
    {
        if(s[i] == 'A')
        {
            cnta++;
        }
        else
        {
            cntb++;
            pozb[cntb] = cnta;
        }
    }

    //for(int i=1;i<=n;i++)cerr<<pozb[i]<<" ";cerr<<"pozb\n";

    assert(cnta == n && cntb == n);

    /*int rez = INF;
    ld st = 0, dr = 1e9;
    for(int pas=0;pas<100;pas++)
    {
        //the greater coef is, the greater cost_song is, so the less songs there are

        ld mij = (st + dr) / 2;
        auto x = solve(mij);
        if(x.second.second == k) rez = min(rez, x.second.first);

        if(x.second.second <= k)
            dr = mij;
        else
            st = mij;
    }
    cout<<rez;*/

    int st = 0, dr = 1e9, ans = -1;
    while(st <= dr)
    {
        int mij = (st + dr) / 2;
        auto x = solve(mij);

        if(x.second.second <= k)
        {
            ans = mij;
            dr = mij - 1;
        }
        else
        {
            st = mij + 1;
        }
    }
    assert(ans != -1);

    auto x = solve(ans);
    cout<<x.first - x.second.second * ans;
    return 0;
}
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…