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"; }