Inilah petunjuk untuk memulai. Menerapkan algoritma pemrograman dinamis standar untuk menghitung sekumpulan partisi integer, dan menambahkan beberapa logika untuk memeriksa yang mana dari yang memungkinkan untuk membuat perubahan unik dengan mengecek semua jumlah, membuat perubahan , dan memverifikasi keunikan secara iteratif .
Dalam sedikit lebih rinci: Misalkan Anda memiliki multiset S . Diberi nomor i dengan 1 ≤ i ≤ n , bagaimana Anda bisa mengidentifikasi submultiset S yang berjumlah i ? Bagaimana Anda bisa mengecek apakah submultiset itu unik? Cobalah untuk mengadaptasi teknik pemrograman dinamis standar untuk membuat perubahan . (Lihat juga pertanyaan ini .)Si1≤i≤nSi
Diberikan multiset S , bagaimana Anda bisa mengecek apakah memenuhi kondisi kedua, yaitu, apakah setiap angka dari 1 hingga n dapat dinyatakan secara unik sebagai jumlah dari sebuah sub-sub S (kondisi perubahan-pembuatan yang unik)? Ini seharusnya cukup mudah, jika Anda memecahkan yang sebelumnya.SnS
misalkan P ( n ) menunjukkan daftar multiset yang memenuhi kedua kondisi Anda. Jika Anda tahu P ( 1 ) , P ( 2 ) , ... , P ( n ) , bagaimana Anda bisa menggunakan informasi itu untuk membangun P ( n + 1 ) ? Di sini Anda mungkin ingin mengadaptasi teknik pemrograman dinamis standar untuk enumerasi partisi integer.P(n)P(1),P(2),…,P(n)P(n+1)
Inilah pendekatan yang mungkin akan lebih baik.
Misalkan S adalah multiset yang memenuhi kedua kondisi Anda (untuk n ). Bagaimana kita bisa memperluasnya untuk mendapatkan T multiset yang memiliki satu elemen lebih? Dengan kata lain, bagaimana kita bisa mengidentifikasi semua cara untuk menambahkan satu elemen lagi ke S , untuk mendapatkan multiset T baru yang memenuhi kedua kondisi Anda (untuk beberapa n ′ )?SnTSTn′
Jawaban: jika x dapat dinyatakan sebagai jumlah dari beberapa elemen S , maka tidak ada gunanya menambahkannya ke S : itu akan menyebabkan T melanggar kondisi keunikan. Jadi, kita dapat menghitung semua bilangan bulat x yang tidak dapat dinyatakan sebagai jumlah dari beberapa elemen S ; masing-masing adalah sesuatu yang berpotensi ditambahkan ke S untuk mendapatkan multiset T baru yang akan memenuhi kedua kondisi (untuk beberapa n lainnya ).xSSTxSSTn
Selain itu, dimungkinkan untuk menyebutkan bilangan bulat mana yang dapat dinyatakan sebagai jumlah dari beberapa elemen S , dan yang tidak bisa, menggunakan pemrograman dinamis. Anda membangun array dua dimensi A [ 1 … | S | , 1 ... n ] dari boolean, di mana A [ i , j ] benar jika ada cara untuk mengekspresikan integer j sebagai jumlah dari beberapa elemen i pertama S (hanya elemen i pertama S yang memenuhi syarat untuk digunakan, di mana SSA[1…|S|,1…n]A[i,j]jiSiSStelah disortir, jadi S = { s 1 , s 2 , … , s k } dan s 1 ≤ s 2 ≤ ⋯ ≤ s k ). Perhatikan bahwa A [ i , j ] dapat dihitung menggunakan nilai-nilai A [ 1 ... i - 1 , 1 ... j - 1 ] : khususnya, A [ i , j ]S={s1,s2,…,sk}s1≤s2≤⋯≤skA[i,j]A[1…i−1,1…j−1]= A [ i - 1 , j ] ∨ A [ i - 1 , j - s i ] jika j > s i , atau A [ i , j ] = A [ i - 1 , j ] jika tidak. Hal ini memungkinkan kita untuk mengidentifikasi semua nomor yang calon yang akan ditambahkan ke S .A[i,j]=A[i−1,j]∨A[i−1,j−si]j>siA[i,j]=A[i−1,j]S
Selanjutnya, untuk setiap kandidat ekstensi T dari S (diperoleh dengan menambahkan satu elemen ke S ), kami ingin memeriksa apakah T memenuhi kedua kondisi. Biarkan n menunjukkan jumlah dari unsur S , dan n ' jumlah dari unsur-unsur T . Kita perlu memeriksa apakah setiap bilangan bulat dalam kisaran n + 1 , n + 2 , ... , n ′ dapat dinyatakan sebagai jumlah dari beberapa elemen TTSSTnSn′Tn+1,n+2,…,n′T. Ini juga dapat diselesaikan dengan menggunakan pemrograman dinamis, menggunakan algoritma standar untuk membuat perubahan. (Faktanya, jika Anda masih memiliki array A yang disebutkan di atas, Anda dapat dengan mudah memperluasnya sedikit untuk menyelesaikan masalah ini: kami menjadikannya array A [ 1 ... | T | , 1 ... n ′ ] , terus isi semua dari entri tambahan, dan pastikan bahwa A [ | T | , n + 1 ] , A [ | T | , n + 2 ] ,AA[1…|T|,1…n′]… , A [ | T | , n ′ ] semuanya benar.) Jadi, sekarang kita dapat menghitung semua multiset T yang memperpanjang S dengan satu elemen dan yang memenuhi kedua kondisi tersebut.A[|T|,n+1],A[|T|,n+2],…,A[|T|,n′]TS
Ini segera menyarankan suatu algoritma untuk menghitung semua multiset S yang memenuhi kondisi Anda, untuk semua n hingga beberapa batasan, katakanlah n ≤ 20 . Kita akan memiliki array P [ 1 ... 20 ] , di mana P [ 5 ] menyimpan semua multiset S yang berjumlah 5, dan secara umum, P [ n ] menyimpan set semua semua multiset S yang menjumlahkan n .Snn≤20P[1…20]P[5]SP[n]Sn
Selanjutnya, kita dapat mengisi P [ n ] secara iteratif. Mulailah dengan mengatur P [ 1 ] untuk memuat hanya satu multiset { 1 } . Berikutnya, untuk setiap n (menghitung dari 1 hingga 20), untuk setiap S ∈ P [ n ] , menyebutkan semua kemungkinan ekstensi T dari S (menggunakan teknik di atas), misalkan n ′ menunjukkan jumlah elemen T , dan masukkan T ke P [ n ′ ]P[n]P[1]{1}nS∈P[n]TSn′TTP[n′]jika belum ada dan jika n ′ ≤ 20 .n′≤20
Ini harusnya bisa dilakukan. Semoga berhasil! Selamat bersenang-senang! Bekerja melalui detail akan menjadi latihan pembelajaran yang baik dalam pemrograman dinamis.