SRM552 FoxPlusMinus

数组first,大小为K。构造一个first的排列F。对于无穷序列A:∀∀i,0<=i < K,则A[i]=F[i];K<=i,则 A[i] = A[i-K] – A[i-K+1] + … + (-1)^(K-1) * A[i-1]。给定N,要求排列F最大化A[N]。若有多种排列满足条件,返回字典序最小的排列(逐个比较排列的数值大小)。
1<=K<=50,-1e9<=first[i]<=1e9,0<=N<=1e9

思路

<1> n < k时需要F[n]最大其余升序排列
<2> k为奇数->F[i]+F[i-1]=F[i-k-1]+F[i-1]即F[i]=F[i-k-1];故使F[n%(k+1)]最大

    int k=F.size();
    res.resize(k);
    sort(F.begin(),F.end());
    if(k&1||N<k){
        N=N%(k+1);
        if(N==k){
            //最大的F[k];
            int p=0;
            for(int i=1;i<k;i+=2)res[i]=F[p++];
            for(int i=0;i<k;i+=2)res[i]=F[p++];
         }else{
             //最大的F[N%(k+1)]
            for(int i=0;i<k;i++){
                if(i<N)res[i]=F[i];
                else if(i==N)res[i]=F[k-1];
                else res[i]=F[i-1];
            }
        }return res;
    }

<3>k为偶数通过枚举可以得到
Ⅰ[0,k)A[N=i]=F[i];
Ⅱ[k,+∞)
->A[N=k]=F[0]-F[1]+F[2]…..-F[k-1]
->A[N=k+1]=F[1]-F[2]…..+F[k-1]-F[k]=-F[0]+2F[1]-2F[2]…..+2F[k-1];//k+1为奇数
->A[N=k+2]=2F[0]-3F[1]+4F[2]……-4F[k-1];//k+2为奇数
容易发现
Ⅰ当N为奇数时其最后一个是+第一个是-
Ⅱ前N-k项的系数是递增的,后面的系数都是相等的(此时按字典序排)

if(N&1){
    int num=k-1;
    for(int i=k-1;i>=0;i-=2)res[i]=A[num--];//正值的为升序
    for(int i=1;i<min(N-k,k);i+=2)res[i]=A[num--];//前面的负值为降序
    for(int i=k-2;i>=N-k;i-=2)res[i]=A[num--];//后面的负值为升序
}else{//同理
    int num=k-1;
    for(int i=k-2;i>=0;i-=2)res[i]=A[num--];
    for(int i=0;i<min(N-k,k);i+=2)res[i]=A[num--];
    for(int i=k-1;i>=N-k;i-=2)res[i]=A[num--];
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值