제출 #1351521

#제출 시각아이디문제언어결과실행 시간메모리
1351521Alex1298조교 (CEOI16_popeala)C++20
100 / 100
1029 ms60432 KiB
//pragma e cel mai op
//de la tle cu 1.5 secunde
//la aprox 1.25 secunde pe cel mai naspa test

#include <iostream>
#include <algorithm>
#pragma GCC target ("avx2")
#pragma GCC optimize ("O3")
#pragma GCC optimize ("unroll-loops")

using namespace std;

int n, t, s;
int points[20005];
int sp[20005];
string st[55];
int results[20005];
int dp[3][20005];
int rmq[55][20][20005];
int last_zero[55][20005];
int temp[55];
int INF = 2e9 + 1;

int query(int st, int dr, int cnt)
{
    if(st > dr)
    {
        swap(st, dr);
    }

    int l = 31 - __builtin_clz(dr - st + 1);
    return min(rmq[cnt][l][st],
               rmq[cnt][l][dr - (1 << l) + 1]);
}

signed main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    cin>>n>>t>>s;
    for(int i = 1; i<=t; i++)
    {
        cin>>points[i];
        sp[i] = sp[i - 1] + points[i];
    }

    for(int i = 1; i<=n; i++)
    {
        cin>>st[i];
        st[i] = '$' + st[i];

        int last = 0;
        for(int j = 1; j<=t; j++)
        {
            if(st[i][j] == '0')
            {
                last = j;
            }
            last_zero[i][j] = last;
        }
    }

    for(int i = 0; i<=t; i++)
    {
        dp[0][i] = INF;
    }
    dp[0][0] = 0;

    int sw = 1;
    for(int sub = 1; sub<=s; sub++)
    {
        for(int i = 0; i<=t; i++)
        {
            dp[sw][i] = INF;
        }

        for(int cnt = 0; cnt<=n; cnt++)
        {
            for(int i = 0; i<=t; i++)
            {
                rmq[cnt][0][i] = dp[1 - sw][i] - cnt * sp[i];
            }

            for(int k = 1; (1 << k) <= t + 1; k++)
            {
                for(int i = 0; i + (1 << k) - 1 <= t; i++)
                {
                    rmq[cnt][k][i] = min(rmq[cnt][k - 1][i], rmq[cnt][k - 1][i + (1 << (k - 1))]);
                }
            }
        }

        for(int i = 1; i<=t; i++)
        {
            for(int j = 1; j<=n; j++)
            {
                temp[j] = last_zero[j][i];
            }

            sort(temp + 1, temp + n + 1);
            reverse(temp + 1, temp + n + 1);
            temp[n + 1] = 0;

            int ind = 1;
            if(temp[1] != i)
            {
                int left = temp[1] + 1;
                dp[sw][i] = min(dp[sw][i], query(left - 1, i - 1, n) + n * sp[i]);

//                cout<<left<<" "<<i<<'\n';
            }

            while(ind <= n)
            {
                if(temp[ind] == 0)
                {
                    break;
                }

                int j = ind + 1;
                while(j <= n && temp[ind] == temp[j])
                {
                    j++;
                }
                j--;

                int left = temp[j + 1] + 1;
                dp[sw][i] = min(dp[sw][i], query(left - 1, temp[j] - 1, n - j) + (n - j) * sp[i]);

//                cout<<left<<" "<<temp[j]<<'\n';

                ind = j + 1;
            }
//            cout<<'\n';

//            cout<<dp[sw][i]<<" ";
        }
//        cout<<'\n';

        cout<<dp[sw][t]<<'\n';
        sw = 1 - sw;
    }

    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...