n_toshi max_t p1,1 p1,2 ・・・ p1,max_t // 1 番目の投資先によって得られる利益 p2,1 p2,2 ・・・ p2,max_t // 2 番目の投資先によって得られる利益 ・・・ pn_toshi,1 pn_toshi,2 ・・・ pn_toshi,max_t
3 4 8 18 22 24 // 1 番目の投資先に 1 単位投資するとその利益は 8,2 単位投資するとその利益は 18,・・・ 3 6 9 12 // 2 番目の投資先に 1 単位投資するとその利益は 3,2 単位投資するとその利益は 6,・・・ 6 7 8 10 // ・・・
4 6 2 0 0 0 0 0 // 1 番目の品物の重さは 1 で,その効用は 2 0 0 5 0 0 0 // 2 番目の品物の重さは 3 で,その効用は 5 0 0 4 0 0 0 // 3 番目の品物の重さは 3 で,その効用は 4 0 0 3 0 0 0 // 4 番目の品物の重さは 3 で,その効用は 3
# -*- coding: UTF-8 -*- #**************************************************/ # 動的計画法:資源配分問題(0-1 ナップザック問題)*/ # ー投資先(品物)毎のデータを出力したい場合ー */ # coded by Y.Suganuma */ #**************************************************/ # データの入力と領域の確保 line = input() a = line.split() n_toshi = int(a[0]) # 投資先数(品物数) max_t = int(a[1]) # 最大投資額(最大重量) max_t += 1 # 投資を行わない(品物を入れない)場合を含めるため table = [] # 投資額と利益(重さと効用) rieki = [] # 投資した際の利益(品物を入れた際の効用) prev = [] # 前段までの投資額(前段までの重さ) for i1 in range(0, n_toshi) : table.append([]) rieki.append([]) prev.append([]) for i1 in range(0, n_toshi) : table[i1].append(0) line = input() a = line.split() for i2 in range(0, max_t-1) : table[i1].append(int(a[i2])) # 動的計画法 # 初期設定(1段目) for i1 in range(0, max_t) : rieki[0].append(table[0][i1]) prev[0].append(-1) # 2段目以降 for i1 in range(1, n_toshi) : for i2 in range(0, max_t) : rieki[i1].append(rieki[i1-1][i2]) prev[i1].append(prev[i1-1][i2]) for i2 in range(0, max_t) : i3 = 0 while i2+i3 < max_t : if rieki[i1-1][i3]+table[i1][i2] > rieki[i1][i2+i3] : rieki[i1][i2+i3] = rieki[i1-1][i3]+table[i1][i2] prev[i1][i2+i3] = i3 i3 += 1 # 結果の出力 k = -1 max = -1 for i1 in range(0, max_t) : if rieki[n_toshi-1][i1] > max : max = rieki[n_toshi-1][i1] k = i1 print("最大利益(最大効用) " + str(max)) for i1 in range(n_toshi-1, 0, -1) : k1 = 0 if rieki[i1][k] != rieki[i1-1][k] : k1 = k - prev[i1][k] k = prev[i1][k] print(" 投資先(品物) " + str(i1+1) + " 投資単位(重さ) " + str(k1) + " 利益(効用) " + str(table[i1][k1])) print(" 投資先(品物) 1 投資単位(重さ) " + str(k) + " 利益(効用) " + str(table[0][k]))
# -*- coding: UTF-8 -*- #**************************************************/ # 動的計画法:資源配分問題(0-1 ナップザック問題)*/ # ー投資先(品物)毎のデータを必要としない場合ー */ # coded by Y.Suganuma */ #**************************************************/ # データの入力と領域の確保 line = input() a = line.split() n_toshi = int(a[0]) # 投資先数(品物数) max_t = int(a[1]) # 最大投資額(最大重量) max_t += 1 # 投資を行わない(品物を入れない)場合を含めるため table = [] # 投資額と利益(重さと効用) rieki = [] # 投資した際の利益(品物を入れた際の効用) for i1 in range(0, n_toshi) : table.append([]) for i1 in range(0, 2) : rieki.append([]) for i1 in range(0, n_toshi) : table[i1].append(0) line = input() a = line.split() for i2 in range(0, max_t-1) : table[i1].append(int(a[i2])) # 動的計画法 # 初期設定(1段目) k1 = 0 k2 = 1 for i1 in range(0, max_t) : rieki[0].append(table[0][i1]) rieki[1].append(0) # 2段目以降 for i1 in range(1, n_toshi) : for i2 in range(0, max_t) : rieki[k2][i2] = rieki[k1][i2] for i2 in range(0, max_t) : i3 = 0 while i2+i3 < max_t : if rieki[k1][i3]+table[i1][i2] > rieki[k2][i2+i3] : rieki[k2][i2+i3] = rieki[k1][i3]+table[i1][i2] i3 += 1 k1 += 1 k1 %= 2 k2 += 1 k2 %= 2 # 結果の出力 max = -1 for i1 in range(0, max_t) : if rieki[k1][i1] > max : max = rieki[k1][i1] print("最大利益(最大効用) " + str(max))
N W w1 v1 // 1 番目の品物の重さとそれを入れた場合の効用 w2 v2 // 2 番目の品物の重さとそれを入れた場合の効用 ・・・ wN vN
4 6 1 2 3 5 3 4 3 3
# -*- coding: UTF-8 -*- #**************************************/ # 動的計画法(0-1ナップザック問題) */ # ー品物毎のデータを出力したい場合ー */ # coded by Y.Suganuma */ #**************************************/ # データの入力と領域の確保 line = input() a = line.split() N = int(a[0]) # 品物の数 W = int(a[1]) # 重さの上限 w = [] # 各品物の重さ v = [] # 各品物の効用 for i1 in range(0, N) : line = input() a = line.split() w.append(int(a[0])) v.append(int(a[1])) # 動的計画法 # 初期設定(1段目) prev = [] # 前段までの品物の重さ dp = [] # ナップザック内の品物の重さ for i1 in range(0, N) : prev.append([]) dp.append([]) for i1 in range(0, W+1) : dp[0].append(-1) prev[0].append(-1) if w[0] <= W : dp[0][w[0]] = v[0] # 2段目以降 for i1 in range(1, N) : for wt in range(0, W+1) : dp[i1].append(dp[i1-1][wt]) prev[i1].append(prev[i1-1][wt]) # 最初の品物である場合 if w[i1] <= W and dp[i1][w[i1]] < v[i1] : dp[i1][w[i1]] = v[i1] prev[i1][w[i1]] = 0 # 過去に品物が入っている場合 for wt in range(1, W+1) : if dp[i1-1][wt] > 0 and wt+w[i1] <= W : if dp[i1-1][wt]+v[i1] > dp[i1][wt+w[i1]] : dp[i1][wt+w[i1]] = dp[i1-1][wt] + v[i1] prev[i1][wt+w[i1]] = wt # 結果の出力 k = -1 ans = -1 for i1 in range(0, W+1) : if dp[N-1][i1] > ans : ans = dp[N-1][i1] k = i1 print("最大効用 " + str(ans)) for i1 in range(N-1, 0, -1) : k1 = 0 if dp[i1][k] != dp[i1-1][k] : k1 = k - prev[i1][k] k = prev[i1][k] vv = v[i1] if k1 <= 0 : vv = 0 print(" 品物 " + str(i1+1) + " 重さ " + str(k1) + " 効用 " + str(vv)) vv = v[0] if k <= 0 : vv = 0 print(" 品物 1 重さ " + str(k) + " 効用 " + str(vv))
# -*- coding: UTF-8 -*- #****************************************/ # 動的計画法(0-1ナップザック問題) */ # ー品物毎のデータを必要としない場合ー */ # coded by Y.Suganuma */ #****************************************/ # データの入力と領域の確保 line = input() a = line.split() N = int(a[0]) # 品物の数 W = int(a[1]) # 重さの上限 w = [] # 各品物の重さ v = [] # 各品物の効用 for i1 in range(0, N) : line = input() a = line.split() w.append(int(a[0])) v.append(int(a[1])) # 動的計画法 # 初期設定(1段目) dp = [] # ナップザック内の品物の重さ for i1 in range(0, 2) : dp.append([]) for i1 in range(0, W+1) : dp[0].append(-1) dp[1].append(-1) if w[0] <= W : dp[0][w[0]] = v[0] k1 = 0 k2 = 1 # 2段目以降 for i1 in range(1, N) : for wt in range(0, W+1) : dp[k2][wt] = dp[k1][wt] # 最初の品物である場合 if w[i1] <= W and dp[k2][w[i1]] < v[i1] : dp[k2][w[i1]] = v[i1] # 過去に品物が入っている場合 for wt in range(1, W+1) : if dp[k1][wt] > 0 and wt+w[i1] <= W : if dp[k1][wt]+v[i1] > dp[k2][wt+w[i1]] : dp[k2][wt+w[i1]] = dp[k1][wt] + v[i1] k1 += 1 k1 %= 2 k2 += 1 k2 %= 2 # 結果の出力 ans = 0 for i1 in range(0, W+1) : if dp[k1][i1] > ans : ans = dp[k1][i1] print("最大効用 " + str(ans))
N M // ノードの数,接続データの数(接続データが無いノード間は移動できない) ni nj rij // ノード ni と ノード nj 間の距離は rij ・・・
7 10 0 1 2 0 2 5 1 2 4 1 3 6 1 4 10 2 3 2 3 5 1 4 5 3 4 6 5 5 6 9
# -*- coding: UTF-8 -*- #******************************************/ # 動的計画法(グラフにおける最短距離問題)*/ # ー経路を出力したい場合ー */ # coded by Y.Suganuma */ #******************************************/ # データの入力と領域の確保 line = input() a = line.split() N = int(a[0]) # ノードの数 M = int(a[1]) # 接続状況データ数 r = [] # ノード間の距離 for i1 in range(0, N) : r.append([]) for i2 in range(0, N) : r[i1].append(0) for i1 in range(0, M) : line = input() a = line.split() k1 = int(a[0]) k2 = int(a[1]) r[k1][k2] = int(a[2]) for i1 in range(0, N-1) : for i2 in range(i1+1, N) : r[i2][i1] = r[i1][i2] # 動的計画法 # 初期設定(1段目) prev = [] # 前のノード dp = [] # ノードへ達するまでの距離 for i1 in range(0, N) : prev.append([]) dp.append([]) for i2 in range(0, N) : prev[i1].append(-1) dp[i1].append(-1) dp[0][0] = 0 # 2段目以降 n = 0 sw = 1 while sw > 0 : sw = 0 for i1 in range(0, N) : dp[n+1][i1] = dp[n][i1] prev[n+1][i1] = prev[n][i1] for i1 in range(0, N) : for i2 in range(0, N) : if dp[n][i1] >= 0 and r[i1][i2] > 0 : if dp[n+1][i2] < 0 or (dp[n][i1]+r[i1][i2] < dp[n+1][i2]) : dp[n+1][i2] = dp[n][i1] + r[i1][i2] prev[n+1][i2] = i1 sw = 1 if sw > 0 : n += 1 # 結果の出力 print("最短距離 " + str(dp[n][N-1])) k = N - 1 print(" ノード番号 " + str(k)) while n > 0 : print(" ノード番号 " + str(prev[n][k])) k = prev[n][k] n -= 1
# -*- coding: UTF-8 -*- #******************************************/ # 動的計画法(グラフにおける最短距離問題)*/ # ー経路を出力する必要が無い場合ー */ # coded by Y.Suganuma */ #******************************************/ # データの入力と領域の確保 line = input() a = line.split() N = int(a[0]) # ノードの数 M = int(a[1]) # 接続状況データ数 r = [] # ノード間の距離 for i1 in range(0, N) : r.append([]) for i2 in range(0, N) : r[i1].append(0) for i1 in range(0, M) : line = input() a = line.split() k1 = int(a[0]) k2 = int(a[1]) r[k1][k2] = int(a[2]) for i1 in range(0, N-1) : for i2 in range(i1+1, N) : r[i2][i1] = r[i1][i2] # 動的計画法 # 初期設定(1段目) dp = [] # ノードへ達するまでの距離 for i1 in range(0, 2) : dp.append([]) for i2 in range(0, N) : dp[i1].append(-1) dp[0][0] = 0 # 2段目以降 sw = 1 k1 = 0 k2 = 1 while sw > 0 : sw = 0 for i1 in range(0, N) : dp[k2][i1] = dp[k1][i1] for i1 in range(0, N) : for i2 in range(0, N) : if dp[k1][i1] >= 0 and r[i1][i2] > 0 : if dp[k2][i2] < 0 or (dp[k1][i1]+r[i1][i2] < dp[k2][i2]) : dp[k2][i2] = dp[k1][i1] + r[i1][i2] sw = 1 if sw > 0 : k1 += 1 k1 %= 2 k2 += 1 k2 %= 2 # 結果の出力 print("最短距離 ", str(dp[k1][N-1]))