1 solutions

  • 0
    @ 2024-6-12 15:13:02

    贪心(100pts)

    • 假设前xx的个最大的家庭在ll的位置,那么我们如果想要疲劳值更大,那么我们只需要枚举ll右边的点【实际上枚举左边的点也没有问题,只是不会更新答案】,可以尝试将最小的aia_i换成ai+2sia_i+2*s_i,最后的最大值就是最后的答案。为了枚举方便,实际上我们是枚举所有小于等于aia_iai+2sia_i+2*s_i
    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+10;
    struct Node{
        int s;
        int a;
    };
    Node node[N];
    bool cmp(Node x,Node y)
    {
        if(x.a>y.a) return true;
        if(x.a==y.a&&x.s>y.s) return true;
        return false;
    }
    //f[i]表示前i个 Ai 的和;
    //g[i]表示前i个 Si 的最大值;
    //s[i]表示i~n中  2Si+Ai  的最大值;
    int f[N],g[N],s[N],res[N];
    int main()
    {
        int n;
      	cin>>n;
        for(int i=1;i<=n;i++) cin>>node[i].s;
        for(int i=1;i<=n;i++) cin>>node[i].a;
        sort(node+1,node+1+n,cmp); //按照疲劳值进行排序 
        for(int i=1;i<=n;i++)
        {
            f[i]=f[i-1]+node[i].a; //前i家的疲劳值 
            g[i]=max(g[i-1],node[i].s); //前i家最远的距离 
        }
        for(int i=n;i;i--)
        {
            s[i]=max(s[i+1],2*node[i].s+node[i].a); //i..n两倍距离+疲劳值最大的点 
        }
        for(int i=1;i<=n;i++)
        {
        	cout<<max(f[i]+g[i]*2,f[i-1]+s[i])<<endl;
            //  (前i个最大的)疲劳最大+2倍距离   前i-1个疲劳+最后一个单独走 
        }
        return 0;
    }
    
    • 1

    Information

    ID
    1050
    Time
    1000ms
    Memory
    256MiB
    Difficulty
    10
    Tags
    # Submissions
    3
    Accepted
    2
    Uploaded By