情報学部 | 菅沼ホーム | 目次 | 索引 |
/* データ例 投資先 3 投資単位 1 ケース数 5 以下,各投資先に資金を投資した場合の利益を入力(ケース数だけ入力) 投資先1 0 8 18 22 24 投資先2 0 3 6 9 12 投資先3 0 6 7 8 10 */ /**********************************/ /* 動的計画法(ナップサック問題) */ /* coded by Y.Suganuma */ /**********************************/ #include <stdio.h> int dynamic(int, int, int, int, int **, int **, int **); int main() { int i1, i2, k, n_toshi, step, n_case, **table, **rieki, **next, max; // データの入力と領域の確保 scanf("%*s %d %*s %d %*s %d", &n_toshi, &step, &n_case); scanf("%*s"); table = new int * [n_toshi]; rieki = new int * [n_toshi]; next = new int * [n_toshi]; for (i1 = 0; i1 < n_toshi; i1++) { table[i1] = new int [n_case]; rieki[i1] = new int [n_case]; next[i1] = new int [n_case]; } for (i1 = 0; i1 < n_toshi; i1++) { scanf("%*s"); for (i2 = 0; i2 < n_case; i2++) scanf("%d", &table[i1][i2]); } // 実行 max = dynamic(0, n_toshi, step, n_case, table, rieki, next); // 結果の出力 if (max >= 0) { printf("最大利益 %d\n", rieki[n_toshi-1][max]); for (i1 = n_toshi-1; i1 >= 0; i1--) { k = max * step; if (i1 > 0) { max = next[i1][max]; k -= max * step; } printf(" 投資先 %d 投資資金 %d\n", i1+1, k); } } else printf("解が存在しません!\n"); return 0; } /*****************************************/ /* 動的計画法によるナップサック問題 */ /* p : 現在計算中の投資先 */ /* n_toshi : 投資先の数 */ /* step : 資金の投資単位 */ /* n_case : 資金の投資ケース数 */ /* table : 投資先,投資金額毎の利益 */ /* rieki : 現段階の最大利益(φ) */ /* next : 最大利益を与える投資先 */ /* coded by Y.Suganuma */ /*****************************************/ int dynamic(int p, int n_toshi, int step, int n_case, int **table, int **rieki, int **next) { int i1, k1, k2, l1, l2, m = 0, m1, m2, max, r; // 最大利益の計算 // 1段目 if (p == 0) { for (i1 = 0; i1 < n_case; i1++) rieki[p][i1] = table[p][i1]; } // 2段目以降 else { for (i1 = 0; i1 < n_case; i1++) { l1 = -1; l2 = -1; max = -1; m = step * i1; m1 = 0; k1 = 0; while (m1 <= m) { m2 = 0; k2 = 0; while (m1+m2 <= m) { r = table[p][k1] + rieki[p-1][k2]; if (r > max) { l1 = k1; l2 = k2; max = r; } m2 += step; k2++; } m1 += step; k1++; } next[p][i1] = l2; if (l2 >= 0) rieki[p][i1] = table[p][l1] + rieki[p-1][l2]; } } // 次の投資先 // 最終段より前 if (p < n_toshi-1) m = dynamic(p+1, n_toshi, step, n_case, table, rieki, next); // 最終段 else { max = -1; k1 = n_toshi - 1; for (i1 = 0; i1 < n_case; i1++) { if (next[k1][i1] >= 0 && rieki[k1][i1] > max) { max = rieki[k1][i1]; m = i1; } } } return m; }
/* データ例 投資先 3 投資単位 1 ケース数 5 以下,各投資先に資金を投資した場合の利益を入力(ケース数だけ入力) 投資先1 0 8 18 22 24 投資先2 0 3 6 9 12 投資先3 0 6 7 8 10 */ /**********************************/ /* 動的計画法(ナップサック問題) */ /* coded by Y.Suganuma */ /**********************************/ import java.io.*; import java.util.*; public class Test { public static void main(String args[]) throws IOException { int i1, i2, k, n_toshi, step, n_case, table[][], rieki[][], next[][], max; StringTokenizer str; String line; BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); // データの入力 // 1 行目 line = in.readLine(); str = new StringTokenizer(line, " "); line = str.nextToken(); line = str.nextToken(); n_toshi = Integer.parseInt(line); line = str.nextToken(); line = str.nextToken(); step = Integer.parseInt(line); line = str.nextToken(); line = str.nextToken(); n_case = Integer.parseInt(line); table = new int [n_toshi][n_case]; rieki = new int [n_toshi][n_case]; next = new int [n_toshi][n_case]; // 2 行目 line = in.readLine(); // 3 行目以降 for (i1 = 0; i1 < n_toshi; i1++) { line = in.readLine(); str = new StringTokenizer(line, " "); line = str.nextToken(); for (i2 = 0; i2 < n_case; i2++) { line = str.nextToken(); table[i1][i2] = Integer.parseInt(line); } } // 実行 max = dynamic(0, n_toshi, step, n_case, table, rieki, next); // 結果の出力 if (max >= 0) { System.out.println("最大利益 " + rieki[n_toshi-1][max]); for (i1 = n_toshi-1; i1 >= 0; i1--) { k = max * step; if (i1 > 0) { max = next[i1][max]; k -= max * step; } System.out.println(" 投資先 " + (i1+1) + " 投資資金 " + k); } } else System.out.println("解が存在しません!"); } /*****************************************/ /* 動的計画法によるナップサック問題 */ /* p : 現在計算中の投資先 */ /* n_toshi : 投資先の数 */ /* step : 資金の投資単位 */ /* n_case : 資金の投資ケース数 */ /* table : 投資先,投資金額毎の利益 */ /* rieki : 現段階の最大利益(φ) */ /* next : 最大利益を与える投資先 */ /* coded by Y.Suganuma */ /*****************************************/ static int dynamic(int p, int n_toshi, int step, int n_case, int table[][], int rieki[][], int next[][]) { int i1, k1, k2, l1, l2, m = 0, m1, m2, max, r; // 最大利益の計算 // 1段目 if (p == 0) { for (i1 = 0; i1 < n_case; i1++) rieki[p][i1] = table[p][i1]; } // 2段目以降 else { for (i1 = 0; i1 < n_case; i1++) { l1 = -1; l2 = -1; max = -1; m = step * i1; m1 = 0; k1 = 0; while (m1 <= m) { m2 = 0; k2 = 0; while (m1+m2 <= m) { r = table[p][k1] + rieki[p-1][k2]; if (r > max) { l1 = k1; l2 = k2; max = r; } m2 += step; k2++; } m1 += step; k1++; } next[p][i1] = l2; if (l2 >= 0) rieki[p][i1] = table[p][l1] + rieki[p-1][l2]; } } // 次の投資先 // 最終段より前 if (p < n_toshi-1) m = dynamic(p+1, n_toshi, step, n_case, table, rieki, next); // 最終段 else { max = -1; k1 = n_toshi - 1; for (i1 = 0; i1 < n_case; i1++) { if (next[k1][i1] >= 0 && rieki[k1][i1] > max) { max = rieki[k1][i1]; m = i1; } } } return m; } }
<!DOCTYPE HTML> <HTML> <HEAD> <TITLE>動的計画法(ナップサック問題)</TITLE> <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8"> <SCRIPT TYPE="text/javascript"> res = ""; /****************/ /* main program */ /****************/ function main() { // データの入力 // 1 行目 let lines = (document.getElementById("data").value).split('\n'); let str = lines[0].split(' ').filter(function(e){return e.length > 0;}); let n_toshi = parseInt(str[1]); let step = parseInt(str[3]); let n_case = parseInt(str[5]); let table = new Array(n_toshi); let rieki = new Array(n_toshi); let next = new Array(n_toshi); for (let i1 = 0; i1 < n_toshi; i1++) { table[i1] = new Array(n_case); rieki[i1] = new Array(n_case); next[i1] = new Array(n_case); } // 3 行目以降 for (let i1 = 0; i1 < n_toshi; i1++) { str = lines[i1+2].split(' ').filter(function(e){return e.length > 0;}); for (let i2 = 0; i2 < n_case; i2++) table[i1][i2] = parseInt(str[i2+1]); } // 実行 let max = dynamic(0, n_toshi, step, n_case, table, rieki, next); // 結果の出力 if (max >= 0) { res += ("最大利益 " + rieki[n_toshi-1][max] + "\n"); for (let i1 = n_toshi-1; i1 >= 0; i1--) { let k = max * step; if (i1 > 0) { max = next[i1][max]; k -= max * step; } res += (" 投資先 " + (i1+1) + " 投資資金 " + k + "\n"); } } else res = "解が存在しません!"; document.getElementById("result").value = res; } /*****************************************/ /* 動的計画法によるナップサック問題 */ /* p : 現在計算中の投資先 */ /* n_toshi : 投資先の数 */ /* step : 資金の投資単位 */ /* n_case : 資金の投資ケース数 */ /* table : 投資先,投資金額毎の利益 */ /* rieki : 現段階の最大利益(φ) */ /* next : 最大利益を与える投資先 */ /* coded by Y.Suganuma */ /*****************************************/ function dynamic(p, n_toshi, step, n_case, table, rieki, next) { // 最大利益の計算 let m = 0; // 1段目 if (p == 0) { for (let i1 = 0; i1 < n_case; i1++) rieki[p][i1] = table[p][i1]; } // 2段目以降 else { for (let i1 = 0; i1 < n_case; i1++) { let l1 = -1; let l2 = -1; let max = -1; let m1 = 0; let k1 = 0; m = step * i1; while (m1 <= m) { let m2 = 0; let k2 = 0; while (m1+m2 <= m) { let r = table[p][k1] + rieki[p-1][k2]; if (r > max) { l1 = k1; l2 = k2; max = r; } m2 += step; k2++; } m1 += step; k1++; } next[p][i1] = l2; if (l2 >= 0) rieki[p][i1] = table[p][l1] + rieki[p-1][l2]; } } // 次の投資先 // 最終段より前 if (p < n_toshi-1) m = dynamic(p+1, n_toshi, step, n_case, table, rieki, next); // 最終段 else { let max = -1; let k1 = n_toshi - 1; for (let i1 = 0; i1 < n_case; i1++) { if (next[k1][i1] >= 0 && rieki[k1][i1] > max) { max = rieki[k1][i1]; m = i1; } } } return m; } </SCRIPT> </HEAD> <BODY STYLE="font-size: 130%; text-align:center; background-color: #eeffee;"> <H2><B>動的計画法(ナップサック問題)</B></H2> <BUTTON STYLE="font-size: 100%; background-color: pink" onClick="return main()">実行</BUTTON><BR> <DIV STYLE="width: 800px; margin-right: auto; margin-left: auto"> <DIV STYLE="text-align:center; float: right; width: 400px"> <DIV STYLE="text-align:center">結果</DIV> <TEXTAREA ID="result" COLS="35" ROWS="10" STYLE="font-size: 100%; width: 380px"> </TEXTAREA> </DIV> <DIV STYLE="text-align:center; width: 400px"> <DIV STYLE="text-align:center">データ</DIV> <TEXTAREA ID="data" COLS="35" ROWS="10" STYLE="font-size: 100%; width: 380px"> 投資先 3 投資単位 1 ケース数 5 以下,各投資先に資金を投資した場合の利益を入力(ケース数だけ入力) 投資先1 0 8 18 22 24 投資先2 0 3 6 9 12 投資先3 0 6 7 8 10 </TEXTAREA> </DIV> </DIV> </BODY> </HTML>
<?php /* データ例 投資先 3 投資単位 1 ケース数 5 以下,各投資先に資金を投資した場合の利益を入力(ケース数だけ入力) 投資先1 0 8 18 22 24 投資先2 0 3 6 9 12 投資先3 0 6 7 8 10 */ /**********************************/ /* 動的計画法(ナップサック問題) */ /* coded by Y.Suganuma */ /**********************************/ // データの入力と領域の確保 fscanf(STDIN, "%*s %d %*s %d %*s %d", $n_toshi, $step, $n_case); $table = array($n_toshi); $rieki = array($n_toshi); $next = array($n_toshi); for ($i1 = 0; $i1 < $n_toshi; $i1++) { $table[$i1] = array($n_case); $rieki[$i1] = array($n_case); $next[$i1] = array($n_case); } fgets(STDIN); for ($i1 = 0; $i1 < $n_toshi; $i1++) { $str = trim(fgets(STDIN)); strtok($str, " "); for ($i2 = 0; $i2 < $n_case; $i2++) $table[$i1][$i2] = intval(strtok(" ")); } // 実行 $max = dynamic(0, $n_toshi, $step, $n_case, $table, $rieki, $next); // 結果の出力 if ($max >= 0) { printf("最大利益 %d\n", $rieki[$n_toshi-1][$max]); for ($i1 = $n_toshi-1; $i1 >= 0; $i1--) { $k = $max * $step; if ($i1 > 0) { $max = $next[$i1][$max]; $k -= $max * $step; } printf(" 投資先 %d 投資資金 %d\n", $i1+1, $k); } } else printf("解が存在しません!\n"); /*****************************************/ /* 動的計画法によるナップサック問題 */ /* p : 現在計算中の投資先 */ /* n_toshi : 投資先の数 */ /* step : 資金の投資単位 */ /* n_case : 資金の投資ケース数 */ /* table : 投資先,投資金額毎の利益 */ /* rieki : 現段階の最大利益(φ) */ /* next : 最大利益を与える投資先 */ /* coded by Y.Suganuma */ /*****************************************/ function dynamic($p, $n_toshi, $step, $n_case, $table, &$rieki, &$next) { $m = 0; // 最大利益の計算 // 1段目 if ($p == 0) { for ($i1 = 0; $i1 < $n_case; $i1++) $rieki[$p][$i1] = $table[$p][$i1]; } // 2段目以降 else { for ($i1 = 0; $i1 < $n_case; $i1++) { $l1 = -1; $l2 = -1; $max = -1; $m = $step * $i1; $m1 = 0; $k1 = 0; while ($m1 <= $m) { $m2 = 0; $k2 = 0; while ($m1+$m2 <= $m) { $r = $table[$p][$k1] + $rieki[$p-1][$k2]; if ($r > $max) { $l1 = $k1; $l2 = $k2; $max = $r; } $m2 += $step; $k2++; } $m1 += $step; $k1++; } $next[$p][$i1] = $l2; if ($l2 >= 0) $rieki[$p][$i1] = $table[$p][$l1] + $rieki[$p-1][$l2]; } } // 次の投資先 // 最終段より前 if ($p < $n_toshi-1) $m = dynamic($p+1, $n_toshi, $step, $n_case, $table, $rieki, $next); // 最終段 else { $max = -1; $k1 = $n_toshi - 1; for ($i1 = 0; $i1 < $n_case; $i1++) { if ($next[$k1][$i1] >= 0 && $rieki[$k1][$i1] > $max) { $max = $rieki[$k1][$i1]; $m = $i1; } } } return $m; } ?>
=begin データ例 投資先 3 投資単位 1 ケース数 5 以下,各投資先に資金を投資した場合の利益を入力(ケース数だけ入力) 投資先1 0 8 18 22 24 投資先2 0 3 6 9 12 投資先3 0 6 7 8 10 =end #*********************************/ # 動的計画法(ナップサック問題) */ # coded by Y.Suganuma */ #*********************************/ #****************************************/ # 動的計画法によるナップサック問題 */ # p : 現在計算中の投資先 */ # n_toshi : 投資先の数 */ # step : 資金の投資単位 */ # n_case : 資金の投資ケース数 */ # table : 投資先,投資金額毎の利益 */ # rieki : 現段階の最大利益(φ) */ # nxt : 最大利益を与える投資先 */ # coded by Y.Suganuma */ #****************************************/ def dynamic(p, n_toshi, step, n_case, table, rieki, nxt) m = 0 # 最大利益の計算 # 1段目 if p == 0 for i1 in 0 ... n_case rieki[p][i1] = table[p][i1] end # 2段目以降 else for i1 in 0 ... n_case l1 = -1 l2 = -1 max = -1 m = step * i1 m1 = 0 k1 = 0 while m1 <= m m2 = 0 k2 = 0 while m1+m2 <= m r = table[p][k1] + rieki[p-1][k2] if r > max l1 = k1 l2 = k2 max = r end m2 += step k2 += 1 end m1 += step k1 += 1 end nxt[p][i1] = l2 if l2 >= 0 rieki[p][i1] = table[p][l1] + rieki[p-1][l2] end end end # 次の投資先 # 最終段より前 if p < n_toshi-1 m = dynamic(p+1, n_toshi, step, n_case, table, rieki, nxt) # 最終段 else max = -1 k1 = n_toshi - 1 for i1 in 0 ... n_case if nxt[k1][i1] >= 0 && rieki[k1][i1] > max max = rieki[k1][i1] m = i1 end end end return m end # データの入力と領域の確保 str = gets() a = str.split(" ") n_toshi = Integer(a[1]) step = Integer(a[3]) n_case = Integer(a[5]) str = gets() table = Array.new(n_toshi) rieki = Array.new(n_toshi) nxt = Array.new(n_toshi) for i1 in 0 ... n_toshi table[i1] = Array.new(n_case) rieki[i1] = Array.new(n_case) nxt[i1] = Array.new(n_case) end for i1 in 0 ... n_toshi str = gets() a = str.split(" ") for i2 in 0 ... n_case table[i1][i2] = Integer(a[i2+1]) end end # 実行 max = dynamic(0, n_toshi, step, n_case, table, rieki, nxt) # 結果の出力 if max >= 0 printf("最大利益 %d\n", rieki[n_toshi-1][max]) i1 = n_toshi-1 while i1 >= 0 k = max * step if i1 > 0 max = nxt[i1][max] k -= max * step end printf(" 投資先 %d 投資資金 %d\n", i1+1, k) i1 -= 1 end else printf("解が存在しません!\n") end
# -*- coding: UTF-8 -*- import numpy as np import sys from math import * """ 入力データ例 投資先 3 投資単位 1 ケース数 5 以下,各投資先に資金を投資した場合の利益を入力(ケース数だけ入力) 投資先1 0 8 18 22 24 投資先2 0 3 6 9 12 投資先3 0 6 7 8 10 """ ############################################ # 動的計画法によるナップサック問題 # p : 現在計算中の投資先 # n_toshi : 投資先の数 # step : 資金の投資単位 # n_case : 資金の投資ケース数 # table : 投資先,投資金額毎の利益 # rieki : 現段階の最大利益(φ) # next : 最大利益を与える投資先 # coded by Y.Suganuma ############################################ def dynamic(p, n_toshi, step, n_case, table, rieki, next) : m = 0 # 最大利益の計算 # 1段目 if p == 0 : for i1 in range(0, n_case) : rieki[p][i1] = table[p][i1] # 2段目以降 else : for i1 in range(0, n_case) : l1 = -1 l2 = -1 max = -1 m = step * i1 m1 = 0 k1 = 0 while m1 <= m : m2 = 0 k2 = 0 while m1+m2 <= m : r = table[p][k1] + rieki[p-1][k2] if r > max : l1 = k1 l2 = k2 max = r m2 += step k2 += 1 m1 += step k1 += 1 next[p][i1] = l2 if l2 >= 0 : rieki[p][i1] = table[p][l1] + rieki[p-1][l2] # 次の投資先 # 最終段より前 if p < n_toshi-1 : m = dynamic(p+1, n_toshi, step, n_case, table, rieki, next) # 最終段 else : max = -1 k1 = n_toshi - 1 for i1 in range(0, n_case) : if next[k1][i1] >= 0 and rieki[k1][i1] > max : max = rieki[k1][i1] m = i1 return m ############################################ # 動的計画法(ナップサック問題) # coded by Y.Suganuma ############################################ # データの入力 line = sys.stdin.readline() s = line.split() n_toshi = int(s[1]) step = int(s[3]) n_case = int(s[5]) line = sys.stdin.readline() table = np.empty((n_toshi, n_case), np.int) rieki = np.empty((n_toshi, n_case), np.int) next = np.empty((n_toshi, n_case), np.int) for i1 in range(0, n_toshi) : line = sys.stdin.readline() s = line.split() for i2 in range(0, n_case) : table[i1][i2] = int(s[i2+1]) # 実行 max = dynamic(0, n_toshi, step, n_case, table, rieki, next) # 結果の出力 if max >= 0 : print("最大利益 " + str(rieki[n_toshi-1][max])) for i1 in range(n_toshi-1, -1, -1) : k = max * step if i1 > 0 : max = next[i1][max] k -= max * step print(" 投資先 " + str(i1+1) + " 投資資金 " + str(k)) else : print("解が存在しません!")
/* データ例 投資先 3 投資単位 1 ケース数 5 以下,各投資先に資金を投資した場合の利益を入力(ケース数だけ入力) 投資先1 0 8 18 22 24 投資先2 0 3 6 9 12 投資先3 0 6 7 8 10 */ /**********************************/ /* 動的計画法(ナップサック問題) */ /* coded by Y.Suganuma */ /**********************************/ using System; class Program { static void Main() { Test1 ts = new Test1(); } } class Test1 { public Test1() { // データの入力 // 1 行目 string[] str = Console.ReadLine().Split(new char[] {' '}, StringSplitOptions.RemoveEmptyEntries); int n_toshi = int.Parse(str[1]); int step = int.Parse(str[3]); int n_case = int.Parse(str[5]); int[][] table = new int [n_toshi][]; int[][] rieki = new int [n_toshi][]; int[][] next = new int [n_toshi][]; for (int i1 = 0; i1 < n_toshi; i1++) { table[i1] = new int [n_case]; rieki[i1] = new int [n_case]; next[i1] = new int [n_case]; } // 2 行目 Console.ReadLine(); // 3 行目以降 for (int i1 = 0; i1 < n_toshi; i1++) { str = Console.ReadLine().Split(new char[] {' '}, StringSplitOptions.RemoveEmptyEntries); for (int i2 = 0; i2 < n_case; i2++) table[i1][i2] = int.Parse(str[i2+1]); } // 実行 int max = dynamic(0, n_toshi, step, n_case, table, rieki, next); // 結果の出力 if (max >= 0) { Console.WriteLine("最大利益 " + rieki[n_toshi-1][max]); for (int i1 = n_toshi-1; i1 >= 0; i1--) { int k = max * step; if (i1 > 0) { max = next[i1][max]; k -= max * step; } Console.WriteLine(" 投資先 " + (i1+1) + " 投資資金 " + k); } } else Console.WriteLine("解が存在しません!"); } /*****************************************/ /* 動的計画法によるナップサック問題 */ /* p : 現在計算中の投資先 */ /* n_toshi : 投資先の数 */ /* step : 資金の投資単位 */ /* n_case : 資金の投資ケース数 */ /* table : 投資先,投資金額毎の利益 */ /* rieki : 現段階の最大利益(φ) */ /* next : 最大利益を与える投資先 */ /* coded by Y.Suganuma */ /*****************************************/ int dynamic(int p, int n_toshi, int step, int n_case, int[][] table, int[][] rieki, int[][] next) { // 最大利益の計算 int m = 0; // 1段目 if (p == 0) { for (int i1 = 0; i1 < n_case; i1++) rieki[p][i1] = table[p][i1]; } // 2段目以降 else { for (int i1 = 0; i1 < n_case; i1++) { int l1 = -1; int l2 = -1; int max = -1; int m1 = 0; int k1 = 0; m = step * i1; while (m1 <= m) { int m2 = 0; int k2 = 0; while (m1+m2 <= m) { int r = table[p][k1] + rieki[p-1][k2]; if (r > max) { l1 = k1; l2 = k2; max = r; } m2 += step; k2++; } m1 += step; k1++; } next[p][i1] = l2; if (l2 >= 0) rieki[p][i1] = table[p][l1] + rieki[p-1][l2]; } } // 次の投資先 // 最終段より前 if (p < n_toshi-1) m = dynamic(p+1, n_toshi, step, n_case, table, rieki, next); // 最終段 else { int max = -1; int k1 = n_toshi - 1; for (int i1 = 0; i1 < n_case; i1++) { if (next[k1][i1] >= 0 && rieki[k1][i1] > max) { max = rieki[k1][i1]; m = i1; } } } return m; } }
* データ例 投資先 3 投資単位 1 ケース数 5 以下,各投資先に資金を投資した場合の利益を入力(ケース数だけ入力) 投資先1 0 8 18 22 24 投資先2 0 3 6 9 12 投資先3 0 6 7 8 10 */ '''''''''''''''''''''''''''''''''' ' 動的計画法(ナップサック問題) ' ' coded by Y.Suganuma ' '''''''''''''''''''''''''''''''''' Imports System.Text.RegularExpressions Module Test Sub Main() ' データの入力 ' 1 行目 Dim MS As Regex = New Regex("\s+") Dim str() As String = MS.Split(Console.ReadLine().Trim()) Dim n_toshi As Integer = Integer.Parse(str(1)) Dim step1 As Integer = Integer.Parse(str(3)) Dim n_case As Integer = Integer.Parse(str(5)) Dim table(n_toshi,n_case) As Integer Dim rieki(n_toshi,n_case) As Integer Dim nxt(n_toshi,n_case) As Integer ' 2 行目 Console.ReadLine() ' 3 行目以降 For i1 As Integer = 0 To n_toshi-1 str = MS.Split(Console.ReadLine().Trim()) For i2 As Integer = 0 To n_case-1 table(i1,i2) = Integer.Parse(str(i2+1)) Next Next ' 実行 Dim max As Integer = dynamic(0, n_toshi, step1, n_case, table, rieki, nxt) ' 結果の出力 If max >= 0 Console.WriteLine("最大利益 " & rieki(n_toshi-1,max)) For i1 As Integer = n_toshi-1 To 0 step -1 Dim k As Integer = max * step1 If i1 > 0 max = nxt(i1,max) k -= max * step1 End If Console.WriteLine(" 投資先 " & (i1+1) & " 投資資金 " & k) Next Else Console.WriteLine("解が存在しません!") End If End Sub ''''''''''''''''''''''''''''''''''''''''' ' 動的計画法によるナップサック問題 ' ' p : 現在計算中の投資先 ' ' n_toshi : 投資先の数 ' ' step1 : 資金の投資単位 ' ' n_case : 資金の投資ケース数 ' ' table : 投資先,投資金額毎の利益 ' ' rieki : 現段階の最大利益(φ) ' ' nxt : 最大利益を与える投資先 ' ' coded by Y.Suganuma ' ''''''''''''''''''''''''''''''''''''''''' Function dynamic(p As Integer, n_toshi As Integer, step1 As Integer, n_case As Integer, table(,) As Integer, rieki(,) As Integer, nxt(,) As Integer) ' 最大利益の計算 Dim m As Integer = 0 ' 1段目 If p = 0 For i1 As Integer = 0 To n_case-1 rieki(p,i1) = table(p,i1) Next ' 2段目以降 Else For i1 As Integer = 0 To n_case-1 Dim l1 As Integer = -1 Dim l2 As Integer = -1 Dim max As Integer = -1 Dim m1 As Integer = 0 Dim k1 As Integer = 0 m = step1 * i1 Do While m1 <= m Dim m2 As Integer = 0 Dim k2 As Integer = 0 Do While m1+m2 <= m Dim r As Integer = table(p,k1) + rieki(p-1,k2) If r > max l1 = k1 l2 = k2 max = r End If m2 += step1 k2 += 1 Loop m1 += step1 k1 += 1 Loop nxt(p,i1) = l2 If l2 >= 0 rieki(p,i1) = table(p,l1) + rieki(p-1,l2) End If Next End If ' 次の投資先 ' 最終段より前 If p < n_toshi-1 m = dynamic(p+1, n_toshi, step1, n_case, table, rieki, nxt) ' 最終段 Else Dim max As Integer = -1 Dim k1 As Integer = n_toshi - 1 For i1 As Integer = 0 To n_case-1 If nxt(k1,i1) >= 0 and rieki(k1,i1) > max max = rieki(k1,i1) m = i1 End If Next End If Return m End Function End Module
情報学部 | 菅沼ホーム | 目次 | 索引 |