Sắp xếp lại bất bình đẳng


10

Lý lịch

Các sắp xếp lại bất bình đẳng là một sự bất bình đẳng đó là dựa trên việc sắp xếp lại số. Nếu tôi có hai danh sách các số có cùng độ dài, x 0 , x 1 , x 2 ... x n-1 và y 0 , y 1 , y 2 ... y n-1 có cùng độ dài, trong đó tôi được phép sắp xếp lại các số trong danh sách, cách tối đa hóa tổng x 0 y 0 + x 1 y 1 + x 2 y 2 + ... + x n-1 y n-1 là sắp xếp 2 danh sách trong thứ tự không giảm.

Đọc bài viết Wikipedia tại đây.

Bài tập

Bạn sẽ viết một chương trình lấy đầu vào từ STDIN hoặc một hàm chấp nhận 2 mảng (hoặc các thùng chứa có liên quan) của các số (có cùng độ dài).

Giả sử bạn viết một hàm chấp nhận 2 mảng (a và b), bạn sẽ tìm số cách bạn có thể sắp xếp lại các số trong mảng thứ hai (b) để tối đa hóa:

a[0]*b[0]+a[1]*b[1]+a[2]*b[2]+...+a[n-1]*b[n-1]

Trong trường hợp này, nếu mảng b là [1 0 , 2 1 , 2 2 , 3 3 , 3 4 ] (chỉ số cho rõ ràng),

[1 0 , 2 1 , 2 2 , 3 3 , 3 4 ],

[1 0 , 2 1 , 2 2 , 3 4 , 3 3 ], (hoán đổi hai 3 giây)

[1 0 , 2 2 , 2 1 , 3 3 , 3 4 ] (hoán đổi hai 2 giây)

[1 0 , 2 2 , 2 1 , 3 4 , 3 3 ] (hoán đổi hai 3 và đổi hai 2)

được coi là sắp xếp khác nhau. Bản thân mảng ban đầu cũng được tính là sự sắp xếp lại có thể nếu nó cũng tối đa hóa tổng.

Đối với đầu vào STDIN, bạn có thể giả sử rằng độ dài của các mảng được cung cấp trước các mảng (vui lòng nêu rõ để bạn sử dụng nó) hoặc các mảng được cung cấp trên các dòng khác nhau (cũng vui lòng nêu rõ).

Dưới đây là 4 đầu vào có thể (để thuận tiện):

5 1 1 2 2 2 1 2 2 3 3 (length before arrays)

1 1 2 2 2 1 2 2 3 3 (the 2 arrays, concatenated)

1 1 2 2 2
1 2 2 3 3 (the 2 arrays on different lines)

5
1 1 2 2 2
1 2 2 3 3 (length before arrays and the 2 arrays on different lines)

Đối với đầu ra, bạn được phép trả lại câu trả lời (nếu bạn viết hàm) hoặc in câu trả lời cho STDOUT. Bạn có thể chọn xuất câu trả lời mod 10 9 +7 (từ 0 đến 10 9 +6) nếu thuận tiện hơn.

Các trường hợp thử nghiệm (và giải thích):

[1 1 2 2 2] [1 2 2 3 3] => 24

2 mục đầu tiên phải là 1 và 2. 3 mục cuối là 2, 3 và 3. Có 2 cách để sắp xếp 2 mục giữa 2 mục đầu tiên và 2 mục cuối. Trong số 2 mục đầu tiên, có 2 cách để sắp xếp lại chúng. Trong số 2 mục cuối cùng, có 6 cách để sắp xếp lại chúng.

[1 2 3 4 5] [6 7 8 9 10] => 1

Chỉ có 1 cách, đó là sự sắp xếp được đưa ra trong các mảng.

[1 1 ... 1 1] [1 1 ... 1 1] (10000 numbers) => 10000! or 531950728

Mọi hoán vị có thể có của mảng thứ hai là hợp lệ.

Bản thử nghiệm của Dennis: Pastebin => 583159312 (mod 1000000007)

Ghi điểm:

Đây là môn đánh gôn, vì vậy câu trả lời ngắn nhất sẽ thắng.

Trong trường hợp hòa, mối quan hệ sẽ bị phá vỡ theo thời gian đệ trình, ủng hộ việc nộp trước đó.

Lưu ý:

Các container có thể không được sắp xếp.

Các số nguyên trong các thùng chứa có thể bằng 0 hoặc âm.

Chương trình phải chạy đủ nhanh (tối đa một giờ) cho các mảng có kích thước khiêm tốn (chiều dài khoảng 10000).

Lấy cảm hứng từ câu hỏi này trên Toán học Stack Exchange.


2
Vui lòng cung cấp một trường hợp thử nghiệm với 10000 phần tử trên mỗi mảng, để chúng tôi có thể xác minh mã của chúng tôi hoạt động chính xác và đủ nhanh.
Dennis

1
Trong ví dụ bạn đưa ra để thay đổi mảng thứ hai [1_0, 2_2, 2_1, 3_4, 3_3] (hoán đổi hai 2 giây và hoán đổi hai 3 giây) bị thiếu
Willem

Bạn có chấp nhận đầu vào như [. . .]plz trả lời không
Abr001am

Nếu chúng ta gửi một hàm, chúng ta có phải lấy hai đối số riêng biệt hay chúng ta có thể lấy một mảng các mảng không?
Dennis

Chà, mảng mảng có vẻ ổn, và không ảnh hưởng quá nhiều đến thử thách. Tôi sẽ làm việc trên trường hợp thử nghiệm.
Element118

Câu trả lời:


4

CJam, 30 26 byte

q~](/:$_za+{e`0f=:m!:*}//*

Hãy thử trực tuyến trong trình thông dịch CJam .

Nó hoàn thành trường hợp thử nghiệm này trong chưa đầy một giây:

$ time cjam <(echo 'q~](/:$_za+{e`0f=:m!:*}%)\:*\/N') < test-large.in | md5sum
5801bbf8ed0f4e43284f7ec2206fd3ff  -

real    0m0.308s
user    0m0.667s
sys     0m0.044s

Chạy nó trong trình thông dịch trực tuyến sẽ mất ít hơn 10 giây.

Thuật toán

Kết quả không phụ thuộc vào thứ tự của A , vì vậy chúng ta có thể giả sử nó được sắp xếp. Điều này có nghĩa là B cũng phải được sắp xếp để đạt được sản phẩm chấm tối đa.

Bây giờ, nếu r 1 , thì r r n là độ dài các lần chạy của A được sắp xếp , có ∏r k ! sự sắp xếp lại khác nhau của các yếu tố của A vẫn dẫn đến thứ tự tăng dần.

Tương tự, nếu s 1 , thì s n là độ dài các lần chạy của B được sắp xếp , có ks k ! sự sắp xếp lại khác nhau của các yếu tố của B vẫn dẫn đến thứ tự tăng dần.

Tuy nhiên, điều này tính tất cả các cặp nhiều lần. Nếu chúng ta lấy cặp của các yếu tố tương ứng của sắp xếp Một và sắp xếp B và xác định t 1 , ... t n là chiều dài của chạy của mảng kết quả, Πt k ! là hệ số nhân đã nói ở trên.

Do đó, kết quả mong muốn là (∏r k !) × (∏s k !) (T k !) .

 q~                          Read and evaluate all input.
   ]                         Wrap the resulting integers in an array.
    (                        Shift out the first (length).
     /                       Split the remainder into chunks of that length.
      :$                     Sort each chunk.
        _z                   Push a copy and transpose rows with columns.
                             This pushes the array of corresponding pairs.
          a+                 Wrap in array and concatenate (append).
            {          }/    For A, B, and zip(A,B):
             e`                Perform run-length encoding.
               0f=             Select the runs.
                  :m!          Apply factorial to each.
                     :*        Reduce by multiplication.
                         /   Divide the second result by the third.
                          *  Multiply the quotient with the first result.

6

Bình thường, 29 28 byte

M/*FPJm*F.!MhMrd8aFCB,SGSHeJ

Hãy thử trực tuyến trong Trình biên dịch Pyth .

Thuật toán

Kết quả không phụ thuộc vào thứ tự của A , vì vậy chúng ta có thể giả sử nó được sắp xếp. Điều này có nghĩa là B cũng phải được sắp xếp để đạt được sản phẩm chấm tối đa.

Bây giờ, nếu r 1 , thì r r n là độ dài các lần chạy của A được sắp xếp , có ∏r k ! sự sắp xếp lại khác nhau của các yếu tố của A vẫn dẫn đến thứ tự tăng dần.

Tương tự, nếu s 1 , thì s n là độ dài các lần chạy của B được sắp xếp , có ks k ! sự sắp xếp lại khác nhau của các yếu tố của B vẫn dẫn đến thứ tự tăng dần.

Tuy nhiên, điều này tính tất cả các cặp nhiều lần. Nếu chúng ta lấy cặp của các yếu tố tương ứng của sắp xếp Một và sắp xếp B và xác định t 1 , ... t n là chiều dài của chạy của mảng kết quả, Πt k ! là hệ số nhân đã nói ở trên.

Do đó, kết quả mong muốn là (r k !) × (∏s k !) (T k !) .

M/*FPJm*F.!MhMrd8aFCB,SGSHeJ

M                             Define g(G,H):
                      SGSH      Sort G and H.
                     ,          For the pair of the results.
                   CB           Bifurcated zip (C).
                                This returns [[SG, SH], zip([SG, SH])].
                 aF             Reduce by appending.
                                This returns [SG, SH, zip([SG, SH])].
      m                         Map; for each d in the resulting array:
              rd8                 Perform run-length encoding on d.
            hM                    Mapped "head". This returns the lengths.
         .!M                      Mapped factorial.
       *F                         Reduce by multiplication.
     J                          Save the result in J.
    P                           Discard the last element.
  *F                            Reduce by multiplication.
 /                  
                          eJ    Divide the product by the last element of J.
                                Return the result of the division.

xác minh

Tôi đã tạo giả ngẫu nhiên 100 trường hợp thử nghiệm có độ dài 6, mà tôi đã giải quyết bằng mã trên và cách tiếp cận mạnh mẽ này:

Ml.Ms*VGZ.pH

M             Define g(G,H) (or n(G,H) on second use):
         .pH    Compute all permutations of H.
  .M            Filter .pH on the maximal value of the following;
                 for each Z in .pH:
     *VGZ         Compute the vectorized product of G and Z.
    s             Add the products.
                  This computes the dot product of G and Z.
 l              Return the length of the resulting array.

Đây là kết quả:

$ cat test.in
6,9,4,6,8,4,5,6,5,0,8,2
0,7,7,6,1,6,1,7,3,3,8,0
3,6,0,0,6,3,8,2,8,3,1,1
2,3,0,4,0,6,3,4,5,8,2,4
9,1,1,2,2,8,8,1,7,4,9,8
8,3,1,1,9,0,2,8,3,4,9,5
2,0,0,7,7,8,9,2,0,6,7,7
0,7,4,2,2,8,6,5,0,5,4,9
2,7,7,5,5,6,8,8,0,5,6,3
1,7,2,7,7,9,9,2,9,2,9,8
7,2,8,9,9,0,7,4,6,2,5,3
0,1,9,2,9,2,9,5,7,4,5,6
8,4,2,8,8,8,9,2,5,4,6,7
5,2,8,1,9,7,4,4,3,3,0,0
9,3,6,2,5,5,2,4,6,8,9,3
4,2,0,6,2,3,5,3,6,3,1,4
4,8,5,2,5,0,5,1,2,5,9,5
6,8,4,4,9,5,9,5,4,2,8,7
8,9,8,1,2,2,9,0,5,6,4,9
4,7,6,8,0,3,7,7,3,9,8,6
7,5,5,6,3,9,3,8,8,4,8,0
3,8,1,8,5,6,6,7,2,8,5,3
0,9,8,0,8,3,0,3,5,9,5,6
4,2,7,7,5,8,4,2,6,4,9,4
3,5,0,8,2,5,8,7,3,4,5,5
7,7,7,0,8,0,9,8,1,4,8,6
3,9,7,7,4,9,2,5,9,7,9,4
4,5,5,5,0,7,3,4,0,1,8,2
7,4,4,2,5,1,7,4,7,1,9,1
0,6,2,5,4,5,1,8,0,8,9,9
3,8,5,3,2,1,1,2,2,2,8,4
6,1,9,1,8,7,5,6,9,2,8,8
6,2,6,6,6,0,2,7,8,6,8,2
0,7,1,4,5,5,3,4,4,0,0,2
6,0,1,5,5,4,8,5,5,2,1,6
2,6,3,0,7,4,3,6,0,5,4,9
1,4,8,0,5,1,3,2,9,2,6,5
2,7,9,9,5,0,1,5,6,8,4,6
4,0,1,3,4,3,6,9,1,2,7,1
6,5,4,7,8,8,6,2,3,4,1,2
0,3,6,3,4,0,1,4,5,5,5,7
5,4,7,0,1,3,3,0,2,1,0,8
8,6,6,1,6,6,2,2,8,3,2,2
7,1,3,9,7,4,6,6,3,1,5,8
4,8,3,3,9,1,3,4,1,3,0,6
1,4,0,7,4,9,8,4,2,1,0,3
0,4,1,6,4,4,4,7,5,1,4,2
0,0,4,4,9,6,7,2,7,7,5,4
9,0,5,5,0,8,8,9,5,9,5,5
5,7,0,4,2,7,6,1,1,1,9,1
3,1,7,5,0,3,1,4,0,9,0,3
4,4,5,7,9,5,0,3,7,4,7,5
7,9,7,3,0,8,4,0,0,3,1,0
2,4,4,3,1,2,5,2,9,0,8,5
4,8,7,3,0,0,9,3,7,3,0,6
8,9,1,0,7,7,6,0,3,1,8,9
8,3,1,7,3,3,6,1,1,7,6,5
6,5,6,3,3,0,0,5,5,0,6,7
2,4,3,9,7,6,7,6,5,6,2,0
4,8,5,1,8,4,4,3,4,5,2,5
7,5,0,4,6,9,5,0,5,7,5,5
4,8,9,5,5,2,3,1,9,7,7,4
1,5,3,0,3,7,3,8,5,5,3,3
7,7,2,6,1,6,6,1,3,5,4,9
9,7,6,0,1,4,0,4,4,1,4,0
3,5,1,4,4,0,7,1,8,9,9,1
1,9,8,7,4,9,5,2,2,1,2,9
8,1,2,2,7,7,6,8,2,3,9,7
3,5,2,1,3,5,2,2,4,7,0,7
9,6,8,8,3,5,2,9,8,7,4,7
8,8,4,5,5,1,5,6,5,1,3,3
2,6,3,5,0,5,0,3,4,4,0,5
2,2,7,6,3,7,1,4,0,3,8,3
4,8,4,2,6,8,5,6,2,5,0,1
7,2,4,3,8,4,4,6,5,3,9,4
4,6,1,0,6,0,2,6,7,4,9,5
6,3,3,4,6,1,0,8,6,1,7,5
8,3,4,2,8,3,0,1,8,9,1,5
9,6,1,9,1,1,8,8,8,9,1,4
3,6,1,6,1,4,5,1,0,1,9,1
6,4,3,9,3,0,5,0,5,3,2,4
5,2,4,6,1,2,6,0,1,8,4,0
3,5,7,6,3,6,4,5,2,8,1,5
6,3,6,8,4,2,7,1,5,3,0,6
9,1,5,9,9,1,1,4,5,7,3,0
1,6,7,3,5,8,6,5,5,2,6,0
2,8,8,6,5,5,2,3,8,1,9,8
0,4,5,3,7,6,2,5,4,3,2,5
5,1,2,3,0,3,4,9,4,9,4,9
5,8,2,2,0,2,4,1,1,7,0,3
0,6,0,0,3,6,3,6,2,2,2,9
2,4,8,1,9,4,0,8,8,0,4,7
3,9,1,0,5,6,8,8,2,5,2,6
5,3,8,9,1,6,5,9,7,7,6,1
8,6,9,6,1,1,6,7,7,3,2,2
7,2,1,9,8,8,5,3,6,3,3,6
9,9,4,8,7,9,8,6,6,0,3,1
8,3,0,9,1,7,4,8,0,1,6,2
8,2,6,2,4,0,2,8,9,6,3,7
1,0,8,5,3,2,3,7,1,7,8,2
$ while read; do
> pyth -c 'M/*FPJm*F.!MhMrd8aFCB,SGSHeJMl.Ms*VGZ.pHAc2Q,gGHnGH' <<< "$REPLY"
> done < test.in
[4, 4]
[4, 4]
[8, 8]
[4, 4]
[8, 8]
[2, 2]
[4, 4]
[4, 4]
[4, 4]
[36, 36]
[2, 2]
[8, 8]
[24, 24]
[8, 8]
[2, 2]
[2, 2]
[6, 6]
[2, 2]
[8, 8]
[2, 2]
[12, 12]
[2, 2]
[8, 8]
[12, 12]
[4, 4]
[12, 12]
[4, 4]
[6, 6]
[8, 8]
[8, 8]
[6, 6]
[4, 4]
[48, 48]
[8, 8]
[4, 4]
[1, 1]
[4, 4]
[4, 4]
[8, 8]
[4, 4]
[12, 12]
[2, 2]
[96, 96]
[2, 2]
[4, 4]
[2, 2]
[6, 6]
[24, 24]
[24, 24]
[48, 48]
[4, 4]
[8, 8]
[12, 12]
[8, 8]
[4, 4]
[2, 2]
[24, 24]
[16, 16]
[2, 2]
[8, 8]
[24, 24]
[4, 4]
[24, 24]
[4, 4]
[12, 12]
[8, 8]
[12, 12]
[4, 4]
[8, 8]
[4, 4]
[16, 16]
[4, 4]
[8, 8]
[8, 8]
[4, 4]
[4, 4]
[4, 4]
[4, 4]
[72, 72]
[24, 24]
[4, 4]
[4, 4]
[4, 4]
[2, 2]
[12, 12]
[4, 4]
[8, 8]
[4, 4]
[36, 36]
[6, 6]
[12, 12]
[8, 8]
[4, 4]
[2, 2]
[8, 8]
[24, 24]
[6, 6]
[1, 1]
[2, 2]
[2, 2]

Để xác minh trình của tôi đáp ứng yêu cầu tốc độ, tôi đã chạy nó với trường hợp thử nghiệm này .

$ time pyth -c 'M/*FPJm*F.!MhMrd8aFCB,SGSHeJAc2QgGH' < test-large.in | md5sum
5801bbf8ed0f4e43284f7ec2206fd3ff  -

real    0m0.233s
user    0m0.215s
sys     0m0.019s

2

Matlab, 230 byte

Chỉnh sửa: Nhiều thứ được cố định để khớp với các trường hợp thử nghiệm của dennis và nnz được thay thế bằng số do giá trị nil.

f=1;t=-1;q=1;a=sort(input(''));b=sort(input(''));for i=unique(a)c=b(find(a==i));r=numel(c(c==t));f=f*factorial(numel(c))*sum(arrayfun(@(u)nchoosek(max(q,r),u),0:min(q,r)));z=c(end);y=numel(c(c==z));q=(t==z)*(q+r)+(t~=z)*y;t=z;end,f

Chấp hành

[2 2 1 2 1]
[3 2 3 2 1]

f =

    24

Dennis 'Testcase:

   A = importdata('f:\a.csv'); for i=1:100,a=sort(A(i,1:6));b=sort(A(i,7:12));
   f=1;t=-1;q=1;for i=unique(a)c=b(find(a==i));r=numel(c(c==t));f=f*factorial(numel(c))*sum(arrayfun(@(u)nchoosek(max(q,r),u),0:min(q,r)));z=c(end);y=numel(c(c==z));q=(t==z)*(q+r)+(t~=z)*y;t=z;end;
   disp(f);end

Đầu ra:

 4

 4

 8

 4

 8

 2

 4

 4

 4

36

 2

 8

24

 8

 2

 2

 6

 2

 8

 2

12

 2

 8

12

 4

12

 4

 6

 8

 8

 6

 4

48

 8

 4

 1

 4

 4

 8

 4

12

 2

96

 2

 4

 2

 6

24

24

48

 4

 8

12

 8

 4

 2

24

16

 2

 8

24

 4

24

 4

12

 8

12

 4

 8

 4

16

 4

 8

 8

 4

 4

 4

 4

72

24

 4

 4

 4

 2

12

 4

 8

 4

36

 6

12

 8

 4

 2

 8

24

 6

 1

 2

 2

Vâng, nó giải quyết vấn đề, vì vậy đầu vào không nên quá quan trọng.
Element118

1

C ++, 503 byte

(chỉ để giải trí, một ngôn ngữ không chơi gôn)

#import<iostream>
#import<algorithm>
#define U 12345
#define l long long
using namespace std;int N,X=1,Y=1,Z=1,x[U],y[U],i=1;l p=1,M=1000000007,f[U];l e(l x,int y){return y?y%2?(x*e(x,y-1))%M:e((x*x)%M,y/2):1;}main(){for(f[0]=1;i<U;i++)f[i]=(f[i-1]*i)%M;cin>>N;for(i=0;i<N;i++)cin>>x[i];for(i=0;i<N;i++)cin>>y[i];sort(x,x+N);sort(y,y+N);for(i=1;i<N;i++)x[i]^x[i-1]?p=p*f[X]%M,X=1:X++,y[i]^y[i-1]?p=p*f[Y]%M,Y=1:Y++,x[i]^x[i-1]|y[i]^y[i-1]?p=p*e(f[Z],M-2)%M,Z=1:Z++;cout<<p*f[X]%M*f[Y]%M*e(f[Z],M-2)%M;}

Phiên bản bị đánh cắp:

#include <cstdio>
#include <algorithm>
#define MOD 1000000007
using namespace std;
int N; // number of integers
int x[1000010]; // the 2 arrays of integers
int y[1000010];
long long product = 1;
long long factorial[1000010]; // storing factorials mod 1000000007
long long factorialInv[1000010]; // storing the inverse mod 1000000007
long long pow(long long x, int y) {
    if (y == 0) return 1;
    if (y == 1) return x;
    if (y%2 == 1) return (x*pow(x, y-1))%MOD;
    return pow((x*x)%MOD, y/2);
}
int main(void) {
    //freopen("in.txt", "r", stdin); // used for faster testing
    //precomputation
    factorial[0] = factorial[1] = 1;
    for (int i=2;i<=1000000;i++) {
        factorial[i] = (factorial[i-1]*i)%MOD;
        factorialInv[i] = pow(factorial[i], MOD-2);
    }
    // input
    scanf("%d", &N);
    for (int i=0;i<N;i++) {
        scanf("%d", &x[i]);
    }
    for (int i=0;i<N;i++) {
        scanf("%d", &y[i]);
    }
    // sort the 2 arrays
    sort(x, x+N);
    sort(y, y+N);
    int sameX = 1;
    int sameY = 1;
    int sameXY = 1;
    for (int i=1;i<N;i++) {
        if (x[i]==x[i-1]) {
            sameX++;
        } else {
            product *= factorial[sameX];
            product %= MOD;
            sameX = 1;
        }
        if (y[i]==y[i-1]) {
            sameY++;
        } else {
            product *= factorial[sameY];
            product %= MOD;
            sameY = 1;
        }
        if (x[i]==x[i-1] && y[i]==y[i-1]) {
            sameXY++;
        } else {
            product *= factorialInv[sameXY];
            product %= MOD;
            sameXY = 1;
        }
    }
    product *= factorial[sameX];
    product %= MOD;
    product *= factorial[sameY];
    product %= MOD;
    product *= factorialInv[sameXY];
    product %= MOD;
    printf("%lld\n", product);
    return 0;
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.