package amphis; import java.util.HashMap; // étant donnée une matrice 15x15, // sélectionner 15 éléments, un par ligne et par colonne, // de façon à maximiser la somme class P345 { final static int m[][] = { { 7, 53, 183, 439, 863, 497, 383, 563, 79, 973, 287, 63, 343, 169, 583 }, { 627, 343, 773, 959, 943, 767, 473, 103, 699, 303, 957, 703, 583, 639, 913 }, { 447, 283, 463, 29, 23, 487, 463, 993, 119, 883, 327, 493, 423, 159, 743 }, { 217, 623, 3, 399, 853, 407, 103, 983, 89, 463, 290, 516, 212, 462, 350 }, { 960, 376, 682, 962, 300, 780, 486, 502, 912, 800, 250, 346, 172, 812, 350 }, { 870, 456, 192, 162, 593, 473, 915, 45, 989, 873, 823, 965, 425, 329, 803 }, { 973, 965, 905, 919, 133, 673, 665, 235, 509, 613, 673, 815, 165, 992, 326 }, { 322, 148, 972, 962, 286, 255, 941, 541, 265, 323, 925, 281, 601, 95, 973 }, { 445, 721, 11, 525, 473, 65, 511, 164, 138, 672, 18, 428, 154, 448, 848 }, { 414, 456, 310, 312, 798, 104, 566, 520, 302, 248, 694, 976, 430, 392, 198 }, { 184, 829, 373, 181, 631, 101, 969, 613, 840, 740, 778, 458, 284, 760, 390 }, { 821, 461, 843, 513, 17, 901, 711, 993, 293, 157, 274, 94, 192, 156, 574 }, { 34, 124, 4, 878, 450, 476, 712, 914, 838, 669, 875, 299, 823, 329, 699 }, { 815, 559, 813, 459, 522, 788, 168, 586, 966, 232, 308, 833, 251, 631, 107 }, { 813, 883, 451, 509, 615, 77, 281, 613, 459, 205, 380, 274, 302, 35, 805 }, }; final static int n = m.length; final static HashMap<Integer, Integer> memo = new HashMap<Integer, Integer>(); // à partir de la ligne i, avec les colonnes dans c static int f(int i, int c) { int key = (i << n) | c; Integer r = memo.get(key); if (r != null) return r; if (i == n) return 0; int s = 0; for (int j = 0; j < n; j++) { int col = 1 << j; if ((c & col) != 0) s = Math.max(s, m[i][j] + f(i + 1, c - col)); } memo.put(key, s); return s; } public static void main(String[] args) { double start = System.currentTimeMillis(); System.out.println("solution = " + f(0, (1 << n) - 1)); System.out.println(System.currentTimeMillis() - start + " ms"); } } // cette fois en déterminant aussi les nombres constituant la somme class P345sol { final static int m[][] = P345.m; final static int n = m.length; // une classe pour mémoriser une somme private static class Solution { int total; int[] rows; Solution() { this.total = 0; this.rows = new int[n]; } Solution(Solution s, int i, int j) { this.total = s.total + m[i][j]; this.rows = new int[n]; System.arraycopy(s.rows, 0, this.rows, 0, n); this.rows[i] = j; } } final static HashMap<Integer, Solution> memo = new HashMap<Integer, Solution>(); // à partir de la ligne i, avec les colonnes dans c static Solution f(int i, int c) { int key = (i << n) | c; Solution s = memo.get(key); if (s != null) return s; s = new Solution(); if (i == n) return s; for (int j = 0; j < n; j++) { int col = 1 << j; if ((c & col) != 0) { Solution r = f(i + 1, c - col); if (m[i][j] + r.total > s.total) s = new Solution(r, i, j); } } memo.put(key, s); return s; } public static void main(String[] args) { double start = System.currentTimeMillis(); Solution s = f(0, (1 << n) - 1); System.out.print("solution = " + s.total + " = "); for (int i = 0; i < n; i++) System.out.printf("%d + ", m[i][s.rows[i]]); System.out.printf("0\n%2.2f ms\n", System.currentTimeMillis() - start); } }