| 情報学部 | 菅沼ホーム | 目次 | 索引 |
/* データ例
投資先 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
| 情報学部 | 菅沼ホーム | 目次 | 索引 |