Submission #696572

#TimeUsernameProblemLanguageResultExecution timeMemory
696572DeepessonLet's Win the Election (JOI22_ho_t3)C++17
56 / 100
2575 ms5480 KiB
#include <bits/stdc++.h>
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")

#define MAX 505
typedef std::pair<double,int> pdd;
typedef std::pair<long long ,long long> pii;
using ll = long long;
int existe[MAX][MAX];
pdd tab[MAX][MAX];
int rodada=52;
int K=0;
std::vector<pii> regs;
int N;
long long C;
double inf = 1LL<<50LL;
pdd dp(int pos,int falta){
    if(pos==N&&!falta)return {0.0,0};
    if(pos==N){
        return {inf,0};
    }
    if(existe[pos][falta]==rodada)return tab[pos][falta];
    existe[pos][falta]=rodada;
    double pegou = (K-falta)+1;
    pdd ans = {inf,0};
    if(falta){
        double custo = (double)regs[pos].first/(double)pegou;
        pdd g = dp(pos+1,falta-1);
        g.first+=custo;
        ans=std::min(ans,g);
    }
    {
        if(regs[pos].second<=C){
            double custo = (double)regs[pos].second/(double)(K+1);
            pdd g = dp(pos+1,falta);
            g.first+=custo-((double)C/(double)(K+1));
            --g.second;
            ans=std::min(ans,g);
        }else {pdd g =dp(pos+1,falta);ans=std::min(ans,g);}
    }
    return tab[pos][falta]=ans;
}
pdd simula(ll kok){
    ++rodada;
    C=kok;
    return dp(0,K);
}
int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);
    int obj;
    std::cin>>N>>obj;
    for(int i=0;i!=N;++i){
        ll a,b;
        std::cin>>a>>b;
        if(b==-1)b=inf;
        regs.push_back({b,a});
    }
    std::sort(regs.begin(),regs.end());
    double ans=inf;
    ll last=1000;
    for(K=0;K<=obj;++K){
        while(K!=obj&&last!=1){
            auto vec = simula(last-1);
            if(abs(vec.second)>=obj-K&&last){
                --last;
            }else break;
        }
        ++rodada;
        C=last;
        auto kek = dp(0,K);
        kek.second*=-1;
        kek.first+=(double)kek.second*((double)last/(double)(K+1));
        ///Pegar quantos a mais selecionei
        ll dif = kek.second-(obj-K);
        ///Descontar os extras (note que eu consigo garantir que o custo eh L)
        kek.first-=((double)(dif*last))/(double)(K+1);
        ans=std::min(ans,kek.first);
    }
    std::cout<<std::fixed<<std::setprecision(20)<<ans<<"\n";
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...