UESTCOJ759 倒推数组

题目

UESTCOJ759 倒推数组_第1张图片
UESTCOJ759 倒推数组_第2张图片

题解

先假设一个数列是单调递增数列 a 0 , a 1 , a 2 , . . . , a n − 2 , a n − 1 . a_0,a_1,a_2,...,a_{n-2},a_{n-1}. a0,a1,a2,...,an2,an1. 我们按照公式 f ( a ) = ∑ i = 1 n ∑ j = 1 n m i n ( a i , a j ) . f(a)=\sum_{i=1}^n \sum_{j=1}^n min(a_i,a_j). f(a)=i=1nj=1nmin(ai,aj). 计算出 f ( a ) f(a) f(a) 的值(在草稿纸上写几项看看取哪些项,比如第一项取 a 0 , a_0, a0,后面 n n n个第二项都比它小,所以取 n n n a 0 a_0 a0;第一项取后面时,都有一个 a 0 a_0 a0要取一次,这里共 n − 1 n-1 n1次,加起来 2 n − 1 2n-1 2n1次,其他系数同理可得)如下:
f ( a ) = ( 2 n − 1 ) a 0 + ( 2 n − 3 ) a 1 + ( 2 n − 5 ) a 2 + . . . + 3 a n − 2 + 1 a n − 1 . f(a)=(2n-1)a_0+(2n-3)a_1+(2n-5)a_2+...+3a_{n-2}+1a_{n-1}. f(a)=(2n1)a0+(2n3)a1+(2n5)a2+...+3an2+1an1.

因为答案是取字典序最小的一组,所以我们令 a 0 = 1 , a 1 = 2 , . . . , a n − 2 = n − 1 , a n − 1 = ? a_0=1,a_1=2,...,a_{n-2}=n-1,a_{n-1}=? a0=1,a1=2,...,an2=n1,an1=?
毕竟我们将这个数组理想化为从最小开始单调递增的,所以很有可能 f ( a ) f(a) f(a)求和结果是达不到 F F F的,故我们先不考虑最后一项 a n − 1 a_{n-1} an1,设 f ( a ) f(a) f(a)前面 ( n − 1 ) (n-1) (n1)项求和结果是 s u m sum sum,而 a n − 1 ≥ n a_{n-1}\ge n an1n,如果让 s u m + n ≥ F sum+n\ge F sum+nF,则找不到最后一项 l a s t last last,使得 s u m + l a s t = = F . sum+last==F. sum+last==F.如果 s u m + n ≤ F sum+n\le F sum+nF,则说明这个理想化的数组按题意公式求和确实不够,那么就让 l a s t = F − s u m last=F-sum last=Fsum.这样输出的前 ( n − 1 ) (n-1) (n1)项就满足字典序最小,第 n n n l a s t last last可以使得 f ( a ) = = F . f(a)==F. f(a)==F.

代码

#include
using namespace std;
int main(){
    int T;
    cin>>T;
    while (T--){
        int n,F;
        cin>>n>>F;
        int sum=0;
        for(int i=n;i>1;i--){
            sum=sum+(2*i-1)*(n-i+1);
        }
        int last;
        if(sum+n>F) cout<<"-1"<<endl;
        else{
            last=F-sum;
            for(int i=1;i<n;i++){
            	cout<<i<<" ";
			}        
            cout<<last<<endl;
        }
    }
    return 0;
}

样例输出

2
2 10
1 7
2 2
-1

,

你可能感兴趣的:(数学方法)