Saya mendapatkan ide soal ini dari soal ACORN untuk ACM/ICPC Asia Regional Contest 2007 Singapore. Ketika itu, USU mengirimkan dua tim untuk acara ini. Tim pertama terdiri dari saya, Alfarisi, Surya Wijaya, dan tim kedua terdiri dari Izhari Ishak Aksa, Ronny Silitonga, Jefri Umar (sebenarnya tim kami yang merupakan tim kedua
). Tim kami tidak berhasil menyelesaikan soal tersebut, sementara tim satunya berhasil. Setelah kembali ke tanah air, saya berhasil menyelesaikannya. Kegagalan ini membuat saya selalu teringat dengan soal tersebut. Pelajaran berharga memang dari pengalaman, pengalaman adalah guru terbaik. Begitu kata teman saya – Yayan – ketika saya berbagi pengalaman ini.
Alice dan Bob merupakan peneliti yang sedang melakukan percobaan mutasi gen. Alice melakukan percobaannya terhadap pohon pisang, sehingga beberapa pohon pisang dapat tumbuh dengan ketinggian yang sama dan memiliki buah di berbagai titik di sepanjang pohon tersebut. Sementara Bob melakukan percobaannya terhadap monyet, sehingga monyet tersebut dapat menyelesaikan permasalahan dengan algoritma tertentu.
Alice dan Bob tinggal bersebelahan. Rumah keduanya memiliki halaman yang hanya terpisah dinding yang cukup tinggi. Di halaman rumah itulah keduanya melakukan percobaannya. Suatu hari, seekor monyet dari halaman rumah Bob secara tidak sengaja memanjat dinding tersebut dan melihat beberapa pohon pisang yang ada di rumah Alice. Melihat banyaknya pisang yang tersebar di pohon-pohon tersebut, monyet tersebut tergoda untuk mengambilnya.
Dari atas dinding, monyet hanya bisa melompat ke salah satu pohon. Selanjutnya ia harus menuruni pohon tersebut sambil mengambil pisang yang dilewatinya. Saat menuruni pohon, ia bisa turun lurus ke bawah sejauh 1 meter atau pindah ke pohon tepat di sebelah kiri atau kanannya sambil turun sejauh 2 meter.
Tentukan berapa jumlah pisang terbanyak yang dapat diambil oleh monyet tersebut.
Sebagai contoh, Alice memiliki 3 pohon pisang dengan ketinggian 5 meter. Pohon pertama memiliki 5 pisang di ketinggian 2 meter, 15 pisang di ketinggian 4 meter, dan 5 pisang di ketinggian 5 meter. Pohon kedua memiliki 20 pisang di ketinggian 2 dan 3 meter. Pohon ketiga memiliki 15 pisang di ketinggian 4 meter. Jika digambarkan menjadi seperti berikut:

Jika monyet memilih pohon pertama lalu turun lurus ke bawah, maka ia akan memperoleh 5 + 15 + 5 = 25 pisang. Jika memilih pohon kedua lalu turun lurus ke bawah, maka ia akan memperoleh 20 + 20 = 40 pisang. Jika memilih pohon ketiga lalu turun lurus ke bawah, maka ia akan memperoleh 15 pisang.
Jika monyet memilih pohon pertama lalu turun ke ketinggian 4 meter di pohon yang sama, kemudian pindah ke pohon kedua ke ketinggian 2 meter, maka ia akan memperoleh 5 + 15 + 20 = 40 pisang.
Tetapi jika monyet memilih pohon pertama, lalu pindah ke pohon kedua ke ketinggian 3 meter, kemudian turun terus ke bawah, maka ia akan memperoleh 5 + 20 + 20 = 45 pisang. Pada test case ini, 45 pisang adalah jumlah maksimum yang dapat diambil.
Ingat: Pindah pohon berarti turun 2 meter, dan monyet hanya bisa pindah ke pohon yang berada tepat di sebelah kiri atau kananya. Sebagai contoh, jika ada empat pohon dan monyet berada di pohon kedua, maka ia bisa pindah ke pohon pertama atau ketiga, tetapi tidak bisa pindah ke pohon keempat.
Input:
Input diawali oleh T (1 <= T <=1000) yang menunjukkan jumlah test case.
Setiap test case terdiri dari beberapa baris. Baris pertama berisi dua buah bilangan bulat N dan H (1 <= N, H <= 50), di mana N merupakan banyaknya pohon pisang setinggi H meter yang terdapat di halaman Alice. N baris berikutnya berisi H buah integer (X1 X2 X3 … XH di mana 0 <= Xi <= 100) yang menunjukkan letak dan jumlah pisang di setiap pohon. Integer pertama (X1) adalah jumlah pisang di ketinggian 1 meter, integer kedua (X2) adalah jumlah pisang di ketinggian 2 meter, integer ketiga (X3) adalah jumlah pisang di ketinggian 3 meter, dst.
Output:
Untik setiap test case, tampilkan jumlah maksimum pisang yang dapat diambil untuk test case tersebut.
Contoh input:
4
3 5
0 5 0 15 5
0 20 20 0 0
0 0 0 15 0
1 1
10
1 10
0 0 0 0 0 0 0 0 0 0
2 5
1 2 3 4 5
1 2 3 4 5
Contoh output:
45
10
0
15
———-
Cara penyelesaian soal ini mirip seperti soal Rute Maksimal (B). Jika pada soal tersebut, yang kita cari adalah maksimum untuk turun ke kiri atau ke kanan, maka pada soal ini yang kita cari adalah maksimum untuk:
- turun lurus (1 langkah ke bawah)
- turun ke kiri (2 langkah ke bawah)
- turun ke kanan (2 langkah ke bawah)
Berikut ini merupakan contoh solusi dalam bahasa Java:
import java.util.Scanner;
import java.util.Arrays;
public class H {
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
int nTC = sc.nextInt();
while (nTC-- > 0) {
int N = sc.nextInt();
int H = sc.nextInt();
int[][] pohon = new int[52][52]; // batasan pada soal: 1 <= N, H <= 50
for (int i = 0; i <= N; i++) {
Arrays.fill(pohon[i], 0);
}
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= H; j++) {
pohon[i][j] = sc.nextInt();
}
}
int hasil = 0; // terbanyak di ketinggian H
// mulai dari baris ke-2 dari bawah sampai paling atas
for (int i = 2; i <= H; i++) {
for (int j = 1; j <= N; j++) {
// cari turun yg optimmal!
int best = pohon[j][i] + pohon[j][i - 1]; // turun lurus
if (j - 1 >= 1 && i - 2 >= 1) {
best = Math.max(best, pohon[j][i] + pohon[j - 1][i - 2]); // turun ke kiri
}
if (j + 1 <= N && i - 2 >= 1) {
best = Math.max(best, pohon[j][i] + pohon[j + 1][i - 2]); // turun ke kanan
}
pohon[j][i] = best; // update!
if (i == H) {
hasil = Math.max(hasil, pohon[j][i]); // update hasil
}
}
}
System.out.println(hasil);
}
}
}
Input dan output yang digunakan oleh juri bisa dilihat di sini.
———-
Untuk soal ACORN, karena time limit untuk soalnya hanya 3 detik, maka tidak bisa menggunakan looping 3 tingkat (pertama untuk mengiterasi setiap ketinggian, kedua untuk mengiterasi setiap pohon, ketiga untuk mengiterasi arah turun). Saya sudah mencoba solusi tersebut dan dinyatakan No – Time Limit Exceeded. Agar mendapatkan Yes/Accepted, harus menggunakan teknik dynamic programming, di mana kita menyimpan maksimum dari tiap-tiap ketinggian di tabel DP (ada juga yang menyebutnya tabel memo). Ini akan meng-eliminasi looping ketiga dengan cara melihat nilai maksimum untuk ketinggian tertentu ke tabel DP tersebut.







Komentar Terkini