Codeforces 731 F. Video Cards(前缀和)


Codeforces 731 F. Video Cards
题目大意:给一组数,从中选一个数作lead,要求其他所有数减少为其倍数,再求和。问所求和的最大值。
思路:统计每个数字出现的个数,再做前缀和,用于之后快速求和。将原数组排序后去重,枚举每一个数做lead的情况下,其余数减少后再求和的结果。不断维护最大值即可。
PS:这里用到了一个方便的函数unique()来去重,使用前需要先将数组排序,参数为数组的首地址和尾后地址,返回新的尾后地址。(该函数没有将重复的元素删除,只是放到了尾地址后面)可以用len=unique(a,a+n)-a得到去重后数组的长度。
附上代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
int a[maxn];
int cnt[maxn*2+5];
int main()
{
    int n,i,j;
    cin>>n;
    for (i=0;i<n;++i)
    {
        scanf("%d",&a[i]);
        cnt[a[i]]++;
    }
    for (i=1;i<maxn*2;++i)
    {
        cnt[i]+=cnt[i-1];
    }
    sort(a,a+n);
    int len=unique(a,a+n)-a; //去重
    ll ans=0; 
    for (i=0;i<len;++i)
    {
        ll sum=0;
        for (j=2;(j-1)*a[i]<=a[len-1];++j)
        {
            int num=cnt[j*a[i]-1]-cnt[(j-1)*a[i]-1];
            sum+=ll(num)*a[i]*(j-1); 
        }
        ans=max(sum,ans);
    }
    cout<<ans;
    return 0;
} 

猜你喜欢

转载自www.cnblogs.com/orangee/p/9016355.html