E. Permutation by Sum

构造一个序列,让l到r里的数总和为s

n<=500

解释代码

now就是说 假如当前位到r,是 len len-1 len-2 ...  3 2 1

就是不重复的最小花费,保证序列不重复

然后跟当前的s比较 如果s不够的填了,说明不能填,因为前面都已经最优填法了

然后找当前位置最优秀的填法 j枚举差值,尽可能在保证不重复的情况下,填最大的

如果都填完了s还有剩下,那l-r一定是 最大的 n n-1 n-2 n-len+1 说明不行,出-1

 

void pre(){
    for(int i=1;i<=500;++i)
        sum[i]=sum[i-1]+i;
}
void solve(){
    memset(a,0,sizeof(a));
    memset(vis,0,sizeof(vis));
    cin>>n>>l>>r>>s;
    for(int i=l;i<=r;++i){
        int now=0,len=r-i+1;
        now=now+sum[len];
        if(s<now){
            cout<<"-1\n";return ;
        }
        int tmp=s-now;//当前项要尽可能填的差值 
        for(int j=tmp;j>=0;--j){
            if(len+j>n||vis[len+j])    continue;
            if(j<=tmp){
                a[i]=len+j;
            //    cout<<"=="<<a[i]<<"\n";
                s=s-a[i];
                vis[a[i]]=1;
                break;
            }
        }
    }
    if(s){
        cout<<"-1\n";return ;
    }
    
    for(int i=1;i<=n;++i){
        if(a[i]==0){
            for(int j=1;j<=n;++j){
                if(vis[j]==0){
                    a[i]=j;vis[j]=1;break;
                }
            }
        }
        cout<<a[i]<<" ";
    }
    cout<<"\n";
}

 

posted @ 2021-04-28 09:55  PdrEam  阅读(108)  评论(0编辑  收藏  举报