Module: Dinamik Programlamada Kalıplar - 2


Problem

4 /5


Cüce

Theory Click to read/hide

Sorumluluk Reddi: Aşağıda açıklanan yöntem evrensel değildir ancak genellikle bir sorunu çözebilir veya doğru çözüme ulaşmanıza yardımcı olabilir.

Bir problemde bir permütasyonun varlığını kontrol etmeniz veya eşleşen permütasyonların sayısını veya benzer bir şeyi bulmanız gerekiyorsa, dinamik altküme programlamayı kullanmayı düşünmelisiniz.

Ana parametre, hangi öğelerin permütasyona dahil edildiğini ve hangilerinin edilmediğini gösteren bir bit maskesi olacaktır. Ayrıca, en son hangi öğenin dahil edildiğini gösteren ikinci bir parametre de sıklıkla gereklidir.

Genellikle permütasyonlar, grafiklerdeki yollar bağlamında görülebilir. Buna göre, klasik bir örnek olan Hamilton yol problemini ele alalım.
Bir Hamilton yolu, grafiğin her köşesinden tam olarak bir kez geçen basit bir yoldur. Basitçe, n'nin köşe sayısı olduğu n uzunluğunun bir permütasyonu olarak temsil edilebilir. Bu permütasyon içindeki sıra, bu yoldaki köşelerin geçildiği sırayı gösterecektir.

Grafikte bir Hamilton yolunun varlığını kontrol etmek için dp[mask][son] dinamiklerini başlatalım - maske bit maskesinde birlerle işaretlenmiş köşeleri atlayan ve son köşede sona eren basit bir yol var mı?
İlk değerler dp[2i][i] = true, geri kalanı false olacaktır, bu da her zaman köşelerden herhangi birinde başlayan boş bir yol olduğu anlamına gelir.
dp[mask][last] içinde true değerine sahip olmak, "yolu genişletmek" anlamında ileriye doğru geçişler yapacağız. Yani, maskede sıfır ile işaretlenmiş köşelerin sayısını arayacağız (yolda henüz ziyaret etmedik) ve aynı zamanda sondan bu köşeye bir kenar olacak şekilde (yol olmalıdır) mevcut bir kenar tarafından uzatılabilir). Yani dp[mask | 2k][k] = true if dp[mask][last] = true AND mask & 2k = 0 (k köşesi henüz ziyaret edilmedi) Ve sonunda bir kenar var -> k.
Nihayetinde, hepsi-birler bit maskesinin parametreleri ve herhangi bir son tepe noktası için dp'de gerçek bir değer varsa, bir Hamilton yolu vardır.

Problem

Cüce Quark bir kez bir hazine haritasına rastladı. Haritada hazinenin bulunabileceği N nokta işaretlenmiştir. Tüm noktalar 1'den N'ye kadar numaralandırılmıştır. Her bir nokta çifti için Quark onları birbirine bağlayan yolun uzunluğunu bilir. Quark, aramaya 1 numaralı noktadan başlar. Kurnaz cüce, uzun yolculuğuna başlamadan önce, kendisine göre hazine olamayacak noktaların üzerini çizer. 1 numaralı noktanın asla çizilmemesi garanti edilir. Bundan sonra Quark, haritada kalan tüm noktalardan geçen bir rota seçer. Rota aynı noktadan birden fazla geçmez. Bir kuark yalnızca kesişmemiş noktaları birleştiren yollarda yürüyebilir.

Quark, minimum uzunlukta bir rota seçmek istiyor. Quark için böyle bir rota bulmak gerekiyor.

Girdi
İlk satır bir tamsayı N (1 ≤ N ≤ 15) içerir — haritada işaretlenmiş noktaların sayısı. Sonraki N satır noktalar arasındaki mesafeleri içerir. (i+1)-inci satırı N tamsayı içerir di1,di2, diN — i'inci noktadan tüm diğerlerine kadar olan yolların uzunlukları. dij=dji, dii=0 ve 0 <dij < 100. (N+2)inci satır bir tamsayı Q (1 < Q & 1000) içerir — bu harita için nokta silme seçeneklerinin sayısı. Aşağıdaki Q satırları, silme seçeneklerinin açıklamasını içerir. Açıklama, C (0 ≤ C <N) — sayısıyla başlar. Quark'a göre hazinenin bulunamayacağı noktaların sayısı. Sonraki C sayıları bu noktaların sayısını verir.

Künye
Q çizgilerini yazdırın. Her satırda bir tamsayı yazdırın — karşılık gelen noktaları silme seçeneği ile minimum rotanın uzunluğu.
Örnekler
# Girdi Çıktı
1 3
0  45 10
45 0  30
10 30 0
2
0
1 3
40
45
2 5
0  14 20 17 14
14 0  15 19 18
20 15 0  15 16
17 19 15 0  14
14 18 16 14 0
2
3 5 4 3
0
14
58