您的位置:首页 > 其它

续续 Codeforces 613 B Skills

2016-01-15 19:16 204 查看
题目传送门:http://codeforces.com/contest/613/problem/B

Two pointers的解法,就是喜欢优美的解法和装逼的姿势!!

首先存储的方式逼格就很高,比起之前的那种分着记录每一项高的多!

然后就是双指针法,外层指针指的是后几个满血的,内指针指的是前几个剩余钱能够满足的能力值最小的,因为随着满血的skill增加,内指针必定是要不断减小的,所以完美地O(n)解决此问题!!!

相比之下还是Two pointers的解法更优一点!

附上优美的英文注释

[code]#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const int MAX=1e5+9;
pair<ll,ll> a[MAX];//store initial skill and id
ll sum[MAX],res[MAX],n,cf,cm,m,A;   
pair<ll,pair<ll,ll>> ans;// store sth we need
int main()
{
    ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin>>n>>A>>cf>>cm>>m;
    for(int i=1;i<=n;i++) cin>>a[i].first,a[i].second=i;
    sort(a+1,a+n+1);
    for(int i=1;i<=n;i++) sum[i]=sum[i-1]+a[i].first;
    ll p=n;
    for(ll i=0;i<=n;i++)
    {
        ll d=m-i*A+sum
-sum[n - i];
        if(d<0) break;
        p=min(p,n-i);
        while(p>1 && d<p*a[p].first-sum[p]) p--;
        d-=p*a[p].first-sum[p];
        ll k=min(A,i==n?A:(a[p].first+d/p));
        //store ans,pos,minleval
        ans=max(ans,{i*cf+k*cm,{i,k}});
    }
    cout<<ans.first<<'\n';
    for(int i=0;i<ans.second.first;i++) a[n-i].first=A;
    for(int i=1;i<=n;i++) a[i].first=max(a[i].first,ans.second.second),res[a[i].second]=a[i].first;
    for(int i=1;i<=n;i++) cout<<res[i]<<" ";
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: