-------------------------i_data-------------------------
期の数 6 段取り費 200 在庫保持費用 1
各期の需要 40 35 50 20 30 35
各期の製造単価 10 10 10 10 10 10
-----------------------program-------------------------
/**************************************/
/* 動的計画法(ロットサイズ決定問題) */
/* coded by Y.Suganuma */
/**************************************/
#include <stdio.h>
void dynamic(int, int, int, int, int, int *, int *, int **, int **);
int main()
{
int i1, h, K, k0, k1 = 0, k2 = 0, n_ki, n_case = 1, *juyou, *seizo, **hiyou, **next;
// データの入力と領域の確保
scanf("%*s %d %*s %d %*s %d", &n_ki, &K, &h);
juyou = new int [n_ki];
seizo = new int [n_ki];
scanf("%*s");
for (i1 = 0; i1 < n_ki; i1++) {
scanf("%d", &juyou[i1]);
n_case += juyou[i1];
}
scanf("%*s");
for (i1 = 0; i1 < n_ki; i1++)
scanf("%d", &seizo[i1]);
hiyou = new int * [n_ki];
next = new int * [n_ki];
for (i1 = 0; i1 < n_ki; i1++) {
hiyou[i1] = new int [n_case];
next[i1] = new int [n_case];
}
// 実行
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)
printf(" 今期の生産量 %d 今期の費用 %d\n", k2-k0, k1-hiyou[i1][k0]);
printf("%d 期: 総費用 %d", i1+1, hiyou[i1][k0]);
if (i1 == 0)
printf(" 今期の生産量 %d 今期の費用 %d\n", k0, hiyou[i1][k0]);
if (i1 != 0) {
k1 = hiyou[i1][k0];
k2 = k0;
k0 = next[i1][k0];
}
}
}
else
printf("解が存在しません!\n");
// 領域の開放
for (i1 = 0; i1 < n_ki; i1++) {
delete [] hiyou[i1];
delete [] next[i1];
}
delete [] hiyou;
delete [] next;
delete [] juyou;
delete [] seizo;
return 0;
}
/****************************************/
/* 動的計画法によるロットサイズ決定問題 */
/* p : 現在の期 */
/* n_ki : 期の数 */
/* n_case : 総需要+1 */
/* K : 段取り費 */
/* h : 在庫保持費用 */
/* juyou : 各期の需要 */
/* seizo : 各期の製造単価 */
/* hiyou : 現段階の最小費用(φ) */
/* next : 前期の対応する最小費用 */
/* coded by Y.Suganuma */
/****************************************/
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)
dynamic(p+1, n_ki, n_case, K, h, juyou, seizo, hiyou, next);
}