Tantangan
Tulis fungsi yang dari array input acak akan memilih semua kombinasi angka dengan jumlah 10.Sekilas, tugasnya sederhana, yang perlu Anda lakukan hanyalah menulis rekursi dan memilah-milah semua nilai.
Atau Anda dapat menggunakan kenaikan biner, tetapi untuk mengulangi semua nilai untuk vektor jumlah panjang N, dibutuhkan 2 ^ n iterasi.
Pertama, kita memilih case khusus, misalkan array terdiri dari angka> 0. Kemudian, berdasarkan contoh ini, kita akan mengimplementasikan semua case.LANGKAH 1
a) Pertimbangkan salah satu kasus khusus - jumlah semua elemen array <10.
Logikanya sederhana, jumlah (V) <10, lalu jumlah (V) -V [i] <jumlah, yaitu, jika jumlah kombinasi akan selalu kurang dari 10.
b) Jika jumlah (V) = 10, maka jumlah jumlah (V) -V [i] <jumlah. Hasilnya hanya satu
v .
LANGKAH 2
Kami menghapus semua yang tidak perlu dari vektor
Sebagai contoh, ambil array [13, 10, 20, 13, 13, 18, 2, 9, 5, 8, 8, 9, 2, 1, 8, 16, 4, 15, 2, 2, 2, 2, 1, 5 , 5, 5].
Ini segera menunjukkan bahwa tidak masuk akal untuk mencari kombinasi jika nilainya> 10, tetapi semuanya akan segera menjadi jelas. jika kita mengurutkannya:
[1, 1, 2, 2, 2, 2, 2, 4, 5, 5, 5, 5, 8, 8, 8, 9, 9, 10, 13, 13, 13, 15, 16, 18, 20 ]
Pada tahap ini, kita sudah bisa tahu pasti bahwa kita perlu menghapus semua elemen yang lebih besar dari 10
v => [1, 1, 2, 2, 2, 2, 2, 4, 5, 5, 5, 5, 8, 8, 8, 9, 9, 10]
Namun faktanya, semuanya sedikit lebih menarik. kita perlu membatasi vektor ke nilai sehingga V [0] + V [i] <= 10; di mana saya cenderung ke N; Tetapi jika V [i] = 10, maka kita tambahkan 10 ke hasilnya
v => [1, 1, 2, 2, 2, 2, 2, 4, 5, 5, 5, 5, 8, 8, 8, 9, 9]
LANGKAH 3
Ada elemen duplikat dalam array yang sudah difilter. Jika kita mendekomposisikan vektor menjadi sub-vektor, dan menghitung jumlahnya, kita mendapatkan sesuatu seperti ini
[1,1] => 2
[2, 2, 2, 2, 2] => 10
[4] => 4
[5, 5, 5, 5] => 20
[8, 8, 8] => 24
[9.9] => 18
Inti dari pikiran saya adalah sedemikian rupa sehingga tidak masuk akal untuk mempertimbangkan kombinasi angka berulang jika jumlah * nilai> 10. Artinya, kita memotong vektor sampai jumlah mereka kurang dari 10, dan menambahkan yang 10 untuk hasilnya:
[1,1] => [1,1]
[2, 2, 2, 2, 2] => [2, 2, 2, 2]
[4] => [4]
[5, 5, 5, 5] => [5]
[8, 8, 8] => [8]
[9.9] => [9]
Sebagai hasil dari langkah ke-3, vektor kita adalah sebagai berikut
[1, 1, 2, 2, 2, 4, 5, 8, 9]
Seperti yang Anda lihat, ukuran vektor telah menurun dari 25 menjadi 9, ukurannya jauh lebih kecil (ingat jumlah iterasi);
Dengan angka negatif
Ini sedikit lebih rumit. kami akan menganggap bahwa kami menerapkan fungsi menemukan kombinasi untuk vektor yang diurutkan positif, berdasarkan batasan sebelumnya.
comb (arr, sum), di mana jumlah adalah jumlah yang diperlukan, arr adalah vektor yang diurutkan dari angka positif
Misalnya, ambil vektor:
[19, 15, -9, 3, -13, -8, -12, 11, -2, -10, 0, 7, 17, -17, -14, -15, -11, -6, -12, , -10, 9]
1. Hancurkan vektorA = hanya nilai positif
B = hanya nilai negatif
Dan lihat juga apakah kita memiliki nilai = 0
2. SortirSortir vektor (naik positif, turun negatif)
Periksa kasus khusus untuk angka positif (LANGKAH 1)
3. Verifikasi positifPeriksa nilai-nilai positif
sisir (B, 10)3. Periksa negatifbuat kombinasi semua angka negatif, tetapi dengan batasan:
(jumlah elemen modulo) <(jumlah semua positif) + 10
kami menemukan kombinasi untuk jumlah referensi BARU (jumlah elemen modulo + 10)
4. Kesetaraan 0Jika vektor sumber memiliki nilai 0, maka kami menambahkan semua kombinasi + 0 ke hasilnya;
Sebagai hasil dari keterbatasan seperti itu, rata-rata, ketika menguji nilai dengan array 28 dan 1000 tes panjang, kenaikan waktu hampir 42%
Berhati-hatilah agar tidak terlihat gugup. Penulis tidak bertanggung jawab atas penderitaan moral.function combine(arr, etalon = 10) {