1 条题解

  • 0
    @ 2026-6-2 23:24:54

    注意到

    设集合AA是选取DP的人员集合,A=k|A|=k,总得分:

    S=iAai+iAbiS=\sum_{i\in A}a_i+\sum_{i\notin A}b_i $$\begin{align} S&=\sum_{i\in A}[b_i+(a_i-b_i)]+\sum_{i\notin A}b_i\\ &=\sum_{i=1}^n b_i+\sum_{i\in A}(a_i-b_i) \end{align}$$

    i=1nbi\displaystyle\sum_{i=1}^n b_i是常数,因此

    maxS    maxiA(aibi)\max S \iff \max\sum_{i\in A}(a_i-b_i)

    贪心:按aibia_i-b_i从大到小排序,选前kk个进AA。 反证:若最优解AA^*不满足,

    $$\exists\ x\in A^*,\ y\notin A^*,\quad a_x-b_x<a_y-b_y$$

    A=(A{x}){y}A'=(A^*\setminus\{x\})\cup\{y\}

    Δ=AA=(ayby)(axbx)>0\Delta=\sum_{A'}-\sum_{A^*}=(a_y-b_y)-(a_x-b_x)>0

    A>A\sum_{A'}>\sum_{A^*},矛盾。 aibia_i-b_i降序,前kkaia_i,剩余取bib_i最优。

    C++

    ll ans;
    bool cmp(pll a,pll b)
    {
        return (a.first-a.second)>(b.first-b.second);
    }
    void solve()
    {
        ll n,m;
        ans=0;
        cin>>n>>m;
        vec<pll>a(n);
        for(int i=0;i<n;++i) cin>>a[i].first>>a[i].second;
        sort(a.begin(),a.end(),cmp);
        for(int i=0;i<n;++i)
        {
            if(i<m) ans+=a[i].first;
            else ans+=a[i].second;
        }
        cout<<ans<<'\n';
    }
    int main()
    {
        AC;
        int t; cin>>t;
        while(t--) solve();
        return 0;
    }
    
    

    Python

    import sys
    def main():
        d=list(map(int,sys.stdin.read().split()))
        p=0
        t=d[p]
        p+=1
        for _ in range(t):
            n,m=d[p],d[p+1]
            p+=2
            a=[]
            for __ in range(n):
                x=d[p]
                y=d[p+1]
                a.append((x,y))
                p+=2
            a.sort(key=lambda x:x[0]-x[1],reverse=True)
            s=0
            for i in range(n):
                if i<m:
                    s+=a[i][0]
                else:
                    s+=a[i][1]
            print(s)
    if __name__=="__main__":main()
    
    
    • 1

    信息

    ID
    1164
    时间
    1000ms
    内存
    256MiB
    难度
    4
    标签
    (无)
    递交数
    3
    已通过
    2
    上传者