LoginSignup
2
4

More than 3 years have passed since last update.

プログラミング問題集(問16〜問20)

Last updated at Posted at 2019-11-11

問16:連立一次方程式(ガウスの消去法)

連立一次方程式を解くアルゴリズムには様々なものがあるが、その中で「ガウスの消去法」について調べ、そのアルゴリズムを説明しなさい。また、次の連立方程式をガウスの消去法で解くプログラムを作成しなさい。ただし、Sympy, Numpy.ligalg, Scipy.ligalg は使わないこと(答え合わせに使うのは良い)。また、参考に用いた書籍またはウェブサイトがある場合はそれを明記すること。

$3 x_1 + 2 x_2 + 7 x_3 + x_4 = 8$
$x_1 + 5 x_2 + x_3 - x_4 = 5$
$4 x_1 + x_2 + 3 x_3 - 2 x_4 = 7$
$x_1 + 6 x_2 + 4 x_3 + 3 x_4 = 13$

問17:連立一次方程式(ヤコブ法)→すみません、解けませんので問題取り消します

連立一次方程式を解くアルゴリズムには様々なものがあるが、その中で「ヤコブ法」について調べ、そのアルゴリズムを説明しなさい。また、次の連立方程式をヤコブ法で解くプログラムを作成しなさい。ただし、Sympy, Numpy.ligalg, Scipy.ligalg は使わないこと(答え合わせに使うのは良い)。参考に用いた書籍またはウェブサイトがある場合はそれを明記すること。

$3 x_1 + 2 x_2 + 7 x_3 + x_4 = 8$
$x_1 + 5 x_2 + x_3 - x_4 = 5$
$4 x_1 + x_2 + 3 x_3 - 2 x_4 = 7$
$x_1 + 6 x_2 + 4 x_3 + 3 x_4 = 13$

問18:ナップサック問題

重さが $W_i$、価値が $V_i$ である $n$ 個のアイテムがあります。これらの中から、重さの和が $x$ を超えない範囲内でアイテムを選んだときの、価値の和の最大値を求めなさい。

ただし、同じアイテムは1個しか選べないものとし、

  • 1 ≤ $n$ ≤ 100
  • 1 ≤ $W_i$ ≤ 100
  • 1 ≤ $V_i$ ≤ 100
  • 10n ≤ $x$ ≤ 100n

とする。

【ヒント】 「動的計画法」で解ける問題として典型的なものです。「再帰」を使って解けます。単純な探索では、同じ計算を繰り返して無駄な時間を使ってしまいます。これを避けるため、計算結果を格納する2次元配列を作って記憶することで、2度目以降の計算を省略するようにしてみましょう。

例18-1

n =  5
x =  175
W =  [95, 56, 65, 54, 32]
V =  [79, 9, 57, 55, 27]
139

例18-2

n =  10
x =  492
W =  [53, 64, 82, 93, 76, 67, 10, 6, 82, 91]
V =  [80, 16, 30, 68, 31, 19, 50, 64, 20, 96]
438

例18-3

n =  20
x =  1371
W =  [30, 31, 100, 83, 52, 97, 34, 70, 96, 13, 70, 89, 79, 51, 31, 93, 73, 10, 77, 31]
V =  [31, 58, 49, 75, 1, 57, 8, 1, 35, 22, 82, 28, 61, 46, 68, 10, 32, 84, 19, 16]
783

例18-4

n =  40
x =  2250
W =  [96, 64, 21, 86, 49, 72, 4, 90, 91, 91, 43, 95, 89, 23, 38, 58, 29, 43, 27, 3, 47, 29, 5, 90, 46, 100, 94, 56, 49, 62, 46, 51, 41, 28, 47, 61, 28, 100, 91, 80]
V =  [74, 83, 57, 64, 63, 58, 100, 59, 66, 66, 85, 55, 86, 25, 41, 64, 26, 1, 87, 88, 73, 98, 57, 63, 31, 69, 21, 79, 96, 13, 2, 50, 89, 10, 11, 93, 45, 31, 15, 67]
2260

例18-5

n =  80
x =  2685
W =  [7, 32, 92, 96, 96, 77, 49, 84, 80, 22, 14, 87, 4, 61, 27, 90, 23, 98, 59, 80, 25, 45, 14, 46, 41, 72, 86, 40, 27, 97, 96, 52, 86, 85, 55, 48, 92, 69, 57, 89, 2, 63, 20, 80, 98, 85, 31, 86, 65, 87, 94, 27, 95, 43, 27, 24, 65, 9, 81, 53, 36, 43, 14, 98, 85, 9, 66, 45, 49, 10, 68, 19, 5, 61, 53, 76, 75, 75, 55, 36]
V =  [71, 6, 45, 90, 41, 89, 5, 57, 19, 78, 79, 100, 9, 45, 84, 41, 90, 18, 100, 34, 60, 6, 7, 82, 64, 40, 17, 44, 85, 94, 33, 90, 36, 50, 46, 66, 6, 57, 36, 4, 15, 50, 23, 94, 99, 26, 33, 95, 16, 45, 6, 93, 37, 89, 13, 52, 4, 92, 86, 10, 41, 12, 85, 43, 98, 92, 57, 38, 75, 61, 66, 1, 74, 61, 91, 33, 35, 96, 13, 17]
3594

例18-6

n =  100
x =  1913
W =  [17, 22, 91, 12, 12, 76, 56, 86, 63, 42, 26, 15, 8, 11, 99, 60, 30, 90, 35, 92, 10, 49, 39, 58, 60, 80, 28, 9, 47, 43, 87, 55, 54, 46, 33, 50, 67, 52, 2, 51, 6, 50, 1, 83, 64, 58, 47, 63, 99, 6, 65, 17, 11, 99, 94, 23, 75, 8, 87, 44, 40, 53, 60, 69, 2, 74, 73, 44, 77, 21, 30, 51, 50, 63, 64, 21, 72, 6, 28, 19, 78, 38, 71, 68, 84, 92, 60, 34, 63, 17, 86, 22, 79, 48, 98, 40, 39, 41, 72, 30]
V =  [47, 44, 4, 11, 94, 44, 20, 2, 61, 59, 31, 20, 87, 18, 16, 79, 2, 2, 58, 31, 67, 35, 19, 39, 30, 15, 63, 31, 70, 13, 35, 50, 20, 18, 6, 8, 49, 13, 44, 60, 65, 5, 51, 15, 84, 74, 50, 34, 35, 91, 97, 18, 54, 27, 3, 29, 86, 44, 74, 94, 85, 75, 92, 66, 83, 34, 63, 74, 8, 62, 25, 68, 45, 59, 28, 54, 75, 98, 8, 35, 98, 42, 22, 51, 48, 43, 29, 73, 68, 41, 78, 62, 61, 4, 44, 91, 10, 35, 22, 51]
3388

参考:例の作り方

import random
n = 10
x = random.randint(n * 10, n * 100)
W = [random.randint(1, 100) for _ in range(n)]
V = [random.randint(1, 100) for _ in range(n)]

問19:最長共通部分列

長さ $n$ の文字列 $s$ と、長さ $m$ の文字列 $t$ を入力としたとき、その2つの文字列の最長共通部分列の長さを求める関数を作りなさい。

ただし、

  • 1 ≤ $n$ ≤ 104
  • 1 ≤ $m$ ≤ 104

とする。

【ヒント】 これも「動的計画法」で解けます。またこの解法は、生命情報学(バイオインフォマティクス」という分野で日常的に用いられる配列相同性検索の基礎となるものです。

例19-1

s = "pencil"
t = "penguin"
4

例19-2

s = "dreamingly"
t = "dreadfully"
6

例19-3

s = "This is a pen. This is an apple."
t = "pen-pineapple-apple-pen"
10

例19-4

s = "There is more to life than increasing its speed. "\
      "(by Mahatma Gandhi)"

t = "There is always light behind the clouds. "\
      "(by Louisa May Alcott)"
31

例19-5

s = "If you want to be successful, it's just this simple: "\
      "Know what you are doing, love what you are doing, "\
      "and believe in what you are doing. "\
      "(by Will Rogers)"

t = "Success is not the key to happiness. "\
      "Happiness is the key to success. "\
      "If you love what you are doing, "\
      "you will be successful. "\
      "(by Louisa May Alcott)"
71

問20:個数制限なしナップサック問題

重さが $W_i$、価値が $V_i$ である $n$ 個のアイテムがあります。これらの中から、重さの和が $x$ を超えない範囲内でアイテムを選んだときの、価値の和の最大値を求めなさい。

ただし、同じアイテムをいくつでも選べるものとし、

  • 1 ≤ $n$ ≤ 100
  • 1 ≤ $W_i$ ≤ 100
  • 1 ≤ $V_i$ ≤ 100
  • 1 ≤ $x$ ≤ 104

とする。

【ヒント】 「同じアイテムをいくつでも選べる」というだけで、問6よりも格段に難しくなります。「同じアイテムをいくつでも」をループとして表現してしまうと、計算量が大きくなりすぎるため避けたいところです。重さの上限が x という条件においてアイテム i を k 個選ぶという状況を、重さの上限が x - Wi という条件においてアイテム i を k - 1 個選ぶという状況と比較して考えます。

例20-1

n = 3
W = [3, 4, 2]
V = [4, 5, 3]
x = 7
10

例20-2

n =  10
x =  867
W =  [28, 92, 30, 1, 40, 33, 96, 30, 38, 86]
V =  [6, 77, 53, 91, 47, 33, 28, 28, 78, 36]
78897

例20-3

n =  20
x =  1272
W =  [10, 87, 38, 74, 19, 93, 34, 24, 63, 12, 31, 99, 45, 4, 22, 81, 50, 75, 36, 20]
V =  [1, 96, 33, 97, 58, 31, 68, 60, 23, 60, 27, 7, 24, 70, 60, 73, 11, 88, 87, 71]
22260

例20-4

n =  40
x =  3309
W =  [20, 5, 85, 84, 10, 15, 80, 24, 48, 96, 33, 18, 22, 58, 62, 24, 12, 73, 76, 9, 53, 7, 47, 82, 69, 82, 57, 33, 60, 10, 84, 16, 97, 9, 57, 92, 22, 1, 70, 26]
V =  [83, 17, 72, 71, 40, 16, 94, 78, 41, 43, 38, 21, 3, 35, 58, 59, 63, 75, 5, 64, 75, 30, 48, 45, 69, 7, 25, 37, 80, 70, 93, 68, 41, 34, 60, 39, 8, 86, 64, 27]
284574

例20-5

n =  40
x =  1747
W =  [60, 76, 2, 14, 89, 88, 83, 27, 55, 10, 53, 58, 60, 45, 90, 73, 32, 54, 90, 97, 28, 54, 10, 70, 73, 61, 5, 14, 35, 65, 57, 12, 9, 85, 98, 51, 49, 13, 98, 16]
V =  [23, 25, 14, 1, 39, 18, 16, 81, 67, 75, 14, 23, 95, 58, 47, 99, 33, 100, 9, 19, 57, 52, 36, 16, 30, 83, 99, 61, 97, 74, 16, 27, 70, 81, 84, 13, 28, 14, 12, 27]
34565

参考:例の作り方

import random
n = 40
x = random.randint(n * 10, n * 100)
W = [random.randint(1, 100) for _ in range(n)]
V = [random.randint(1, 100) for _ in range(n)]

print("n = ", n)
print("x = ", x)
print("W = ", W)
print("V = ", V)
2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4