-------------------------i_data------------------------- 期の数 6 段取り費 200 在庫保持費用 1 各期の需要 40 35 50 20 30 35 各期の製造単価 10 10 10 10 10 10 ------------------------program------------------------ /**************************************/ /* 動的計画法(ロットサイズ決定問題) */ /* coded by Y.Suganuma */ /**************************************/ import java.io.*; import java.util.StringTokenizer; class Test { public static void main(String args[]) throws IOException { int i1, h, K, k0, k1 = 0, k2 = 0, n_ki, n_case = 1, juyou[], seizo[], hiyou[][], next[][]; String str; StringTokenizer dt; BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); // データの入力と領域の確保 str = in.readLine(); dt = new StringTokenizer(str, " "); dt.nextToken(); n_ki = Integer.parseInt(dt.nextToken()); dt.nextToken(); K = Integer.parseInt(dt.nextToken()); dt.nextToken(); h = Integer.parseInt(dt.nextToken()); juyou = new int [n_ki]; seizo = new int [n_ki]; str = in.readLine(); dt = new StringTokenizer(str, " "); dt.nextToken(); for (i1 = 0; i1 < n_ki; i1++) { juyou[i1] = Integer.parseInt(dt.nextToken()); n_case += juyou[i1]; } str = in.readLine(); dt = new StringTokenizer(str, " "); dt.nextToken(); for (i1 = 0; i1 < n_ki; i1++) seizo[i1] = Integer.parseInt(dt.nextToken()); hiyou = new int [n_ki][n_case]; next = new int [n_ki][n_case]; // 実行 App.dynamic(0, n_ki, n_case, K, h, juyou, seizo, hiyou, next); // 結果の出力 k0 = n_case - 1; if (hiyou[n_ki-1][k0] >= 0) { for (i1 = n_ki-1; i1 >= 0; i1--) { if (i1 < n_ki-1) System.out.println(" 今期の生産量 " + (k2-k0) + " 今期の費用 " + (k1-hiyou[i1][k0])); System.out.print((i1+1) + " 期: 総費用 " + hiyou[i1][k0]); if (i1 == 0) System.out.println(" 今期の生産量 " + k0 + " 今期の費用 " + hiyou[i1][k0]); if (i1 != 0) { k1 = hiyou[i1][k0]; k2 = k0; k0 = next[i1][k0]; } } } else System.out.println("解が存在しません!"); } } /************************ /* 科学技術系算用の手法 */ /************************/ class App { /****************************************/ /* 動的計画法によるロットサイズ決定問題 */ /* p : 現在の期 */ /* n_ki : 期の数 */ /* n_case : 総需要+1 */ /* K : 段取り費 */ /* h : 在庫保持費用 */ /* juyou : 各期の需要 */ /* seizo : 各期の製造単価 */ /* hiyou : 現段階の最小費用(φ) */ /* next : 前期の対応する最小費用 */ /* coded by Y.Suganuma */ /****************************************/ static void dynamic(int p, int n_ki, int n_case, int K, int h, int juyou[], int seizo[], int hiyou[][], int next[][]) { int i1, i2, k1, k2, k3, m = 0, min, n_c = 0, v; // 最小費用の計算 // 1期目 if (p == 0) { for (i1 = 0; i1 < n_case; i1++) { next[p][i1] = -1; hiyou[p][i1] = -1; } for (i1 = juyou[0]; i1 < n_case; i1++) hiyou[p][i1] = K + i1 * seizo[p]; } // 2期目以降 else { for (i1 = 0; i1 < n_case; i1++) { hiyou[p][i1] = -1; next[p][i1] = -1; } for (i1 = p; i1 < n_ki; i1++) // 今期以降の総需要 n_c += juyou[i1]; k2 = n_case - 1 - n_c; // 前期までの総需要 k1 = k2 + juyou[p]; // 今期までの総需要 for (i1 = k1; i1 < n_case; i1++) { // i1 : 今期までの総生産量 min = -1; m = -1; for (i2 = 0; i1-i2 >= k2; i2++) { // i2 : 今期の生産量 k3 = i1 - i2; v = (i2 == 0) ? 0 : K + i2 * seizo[p]; // 今期の製造費 v += hiyou[p-1][k3]; // 前期までの総費用 v += h * (k3 - k2); // 在庫維持費 if (min < 0 || min >= 0 && v < min) { min = v; m = k3; } } next[p][i1] = m; if (m >= 0) hiyou[p][i1] = min; } } // 次の期 if (p < n_ki-1) App.dynamic(p+1, n_ki, n_case, K, h, juyou, seizo, hiyou, next); } }