Python-再帰とダイナミックプランニング
5062 ワード
タイトル1:
与えられた配列arrは、arr内のすべての値が正数であり、重複しない.各値は1種の額面の貨幣を代表して、各額面の貨幣は任意の枚を使うことができて、更に1つの整数aimが探している金額を代表して、aimを構成する最低の貨幣数を求めます.
例arr=[5,2,10,1],aim=5
考え方:
1、len(arr)行aim+1列行列を定義し、デフォルト値は最大値である.
2、初期化、第1列は0で、第1行は以下の各代表で、aim=0、1、2、3、4、5まで、1枚5元しかかかりません.
0 max max max max 1
0
0
0
3、dp[i][j] = min{dp[i-1][j], dp[i][j-arr[i]+1]}
dp[i-1][j]は、ローの値を使用しないで直接使用することを表し、dp[i][j-arr[i]+1はローの使用を表す
問題1補足:
与えられた配列arrは、arr内のすべての値が正数であり、重複しない.各値は1枚のお金の額面を表し、各額面の通貨は1枚使用することができ、整数aimを与えて探しているお金の数を表し、aimを構成する最小の通貨数を求める.
1、前の問題の第一歩と同じです.
2、最初の列は前の問題と同じで、最初の行はarr[0]の位置だけを1にします.
3、dp[i][j]=min(dp[i-1][j],dp[i-1][j-arr[i]])
dp[i-1][j]は、ロー通貨を使用しないことを意味する
dp[i-1][j-arr[i]]は、ロー通貨の使用を表します.
タイトル2:
与えられた配列arrは、arr内のすべての値が正数であり、重複しない.各値は1種の額面の貨幣を代表して、各額面の貨幣は任意の枚を使うことができて、更に1つの整数aimが探している金額を代表して、両替を求めるのはどれだけの方法がありますか.
例arr=[5,2,10,1],aim=5
考え方:
1、len(arr)行aim+1列マトリクスを定義し、デフォルト値は0です.
2、初期化、第1列は1で、各面の値を表すのはすべて使わないで、1つの方案があって、第1行は以下の各代表で、aim=0、1、2、3、4、5、5まで、1枚5元しか必要ありません.
1 0 0 0 0 1
1 0 1 0 1 0
1
1
3、num=dp[i-1][j-arr[i]*k] for k in range(aim+1); dp[i][j] = num
dp[i-1][j]は、ローの値を使用しないで直接使用することを表し、dp[i][j-arr[i]+1はローの使用を表す
最適化手順3:
dp[i][j] = dp[i-1][j]+dp[i][j-arr[i]]
タイトル3:
k個の整数+のシーケンス{N 1,N 2,...,Nk}が与えられ、その任意の連続サブシーケンスは{Ni,Ni+1,...,Nj}として表すことができ、そのうち1<=i<=j<=kである.最大連続サブシーケンスは、すべての連続サブシーケンスの要素と最大の1つであり、例えば、所与のシーケンス{−2,11,−4,13,−5,−2}であり、その最大連続サブシーケンスは{11,−4,13}、最大連続サブシーケンスおよびすなわち20である.
問題3拡張:
積の最大シーケンスを出力します.
タイトル4:
アレックスと李はいくつかの石でゲームをしています.偶数の石が1列に並んでいて、各山には正の整数の石
ゲームは誰の手の中の石が一番多いかで勝負を決める.石の総数は奇数なので引き分けはありません.
アレックスと李は交代で行い、アレックスは先に始めた.ラウンドごとに、プレイヤーは行の開始または終了から石の山全体を取り出します.このような状況は、より多くの石の山がないまで続き、この時、手にした石が最も多いプレイヤーが勝った.
アレックスと李が最高のレベルを発揮したと仮定すると、アレックスが試合に勝ったときは
例:
与えられた配列arrは、arr内のすべての値が正数であり、重複しない.各値は1種の額面の貨幣を代表して、各額面の貨幣は任意の枚を使うことができて、更に1つの整数aimが探している金額を代表して、aimを構成する最低の貨幣数を求めます.
例arr=[5,2,10,1],aim=5
考え方:
1、len(arr)行aim+1列行列を定義し、デフォルト値は最大値である.
2、初期化、第1列は0で、第1行は以下の各代表で、aim=0、1、2、3、4、5まで、1枚5元しかかかりません.
0 max max max max 1
0
0
0
3、dp[i][j] = min{dp[i-1][j], dp[i][j-arr[i]+1]}
dp[i-1][j]は、ローの値を使用しないで直接使用することを表し、dp[i][j-arr[i]+1はローの使用を表す
def findmoney(arr,aim):
max=float('inf')
l = [[max for i in range(aim+1)] for i in range(len(arr))]
for i in range(len(arr)):
l[i][0]=0
for i in range(1,aim//arr[0]+1):
l[0][i*arr[0]]=i
for i in range(1,len(arr)):
for j in range(1,aim+1):
left=max
if j-arr[i]>=0:
left=l[i][j-arr[i]]+1
l[i][j]=min(l[i-1][j],left)
print(l)
findmoney([5,2,10,1],20)
問題1補足:
与えられた配列arrは、arr内のすべての値が正数であり、重複しない.各値は1枚のお金の額面を表し、各額面の通貨は1枚使用することができ、整数aimを与えて探しているお金の数を表し、aimを構成する最小の通貨数を求める.
1、前の問題の第一歩と同じです.
2、最初の列は前の問題と同じで、最初の行はarr[0]の位置だけを1にします.
3、dp[i][j]=min(dp[i-1][j],dp[i-1][j-arr[i]])
dp[i-1][j]は、ロー通貨を使用しないことを意味する
dp[i-1][j-arr[i]]は、ロー通貨の使用を表します.
def findmoney(arr,aim):
max=float('inf')
l = [[max for i in range(aim+1)] for i in range(len(arr))]
for i in range(len(arr)):
l[i][0]=0
l[0][arr[0]]=1
for i in range(1,len(arr)):
for j in range(1,aim+1):
left=max
if j-arr[i]>=0:
left=l[i-1][j-arr[i]]+1
l[i][j]=min(l[i-1][j],left)
print(l)
print(l[i][j])
findmoney([5,2,10,1],15)
タイトル2:
与えられた配列arrは、arr内のすべての値が正数であり、重複しない.各値は1種の額面の貨幣を代表して、各額面の貨幣は任意の枚を使うことができて、更に1つの整数aimが探している金額を代表して、両替を求めるのはどれだけの方法がありますか.
例arr=[5,2,10,1],aim=5
考え方:
1、len(arr)行aim+1列マトリクスを定義し、デフォルト値は0です.
2、初期化、第1列は1で、各面の値を表すのはすべて使わないで、1つの方案があって、第1行は以下の各代表で、aim=0、1、2、3、4、5、5まで、1枚5元しか必要ありません.
1 0 0 0 0 1
1 0 1 0 1 0
1
1
3、num=dp[i-1][j-arr[i]*k] for k in range(aim+1); dp[i][j] = num
dp[i-1][j]は、ローの値を使用しないで直接使用することを表し、dp[i][j-arr[i]+1はローの使用を表す
def findmoney(arr,aim):
# max=float('inf')
# max=float('inf')
# num=0
l = [[0 for i in range(aim+1)] for i in range(len(arr))]
for i in range(len(arr)):
l[i][0]=1
for i in range(1,aim//arr[0]+1):
l[0][i*arr[0]]=1
for i in range(1,len(arr)):
for j in range(1,aim+1):
num=0
for k in range(aim+1):
if j-arr[i]*k>=0:
num+=l[i-1][j-k*arr[i]]
l[i][j]=num
print(l)
print(l[i][j])
findmoney([5,2,10,1],10)
最適化手順3:
dp[i][j] = dp[i-1][j]+dp[i][j-arr[i]]
def findmoney(arr,aim):
# max=float('inf')
# max=float('inf')
# num=0
l = [[0 for i in range(aim+1)] for i in range(len(arr))]
for i in range(len(arr)):
l[i][0]=1
for i in range(1,aim//arr[0]+1):
l[0][i*arr[0]]=1
for i in range(1,len(arr)):
for j in range(1,aim+1):
l[i][j]=l[i-1][j]
if j-arr[i]>=0:
l[i][j]+=l[i][j-arr[i]]
print(l)
print(l[i][j])
findmoney([5,2,10,1],10)
タイトル3:
k個の整数+のシーケンス{N 1,N 2,...,Nk}が与えられ、その任意の連続サブシーケンスは{Ni,Ni+1,...,Nj}として表すことができ、そのうち1<=i<=j<=kである.最大連続サブシーケンスは、すべての連続サブシーケンスの要素と最大の1つであり、例えば、所与のシーケンス{−2,11,−4,13,−5,−2}であり、その最大連続サブシーケンスは{11,−4,13}、最大連続サブシーケンスおよびすなわち20である.
def findmax(arr):
n=len(arr)
l=[0 for i in range(n)]
l[0]=arr[0]
for i in range(1,n):
l[i]=max(arr[i]+l[i-1],arr[i])
print(max(l))
findmax([-2,11,-4,13,-5,-2,14])
問題3拡張:
積の最大シーケンスを出力します.
def find(arr):
n=len(arr)
l=[0 for i in range(n)]
g=[0 for i in range(n)]
l[0]=arr[0]
g[0]=arr[0]
for i in range(1,n):
l[i]=max(l[i-1]*arr[i],arr[i],g[i-1]*arr[i])
g[i]=min(l[i-1]*arr[i],arr[i],g[i-1]*arr[i])
print(l[-1])
find([-2, 11, -4, 13, -5, -2])
タイトル4:
アレックスと李はいくつかの石でゲームをしています.偶数の石が1列に並んでいて、各山には正の整数の石
piles[i]
があります.ゲームは誰の手の中の石が一番多いかで勝負を決める.石の総数は奇数なので引き分けはありません.
アレックスと李は交代で行い、アレックスは先に始めた.ラウンドごとに、プレイヤーは行の開始または終了から石の山全体を取り出します.このような状況は、より多くの石の山がないまで続き、この時、手にした石が最も多いプレイヤーが勝った.
アレックスと李が最高のレベルを発揮したと仮定すると、アレックスが試合に勝ったときは
true
、李が試合に勝ったときはfalse
に戻る.例:
:[5,3,4,5]
:true
:
, 5 5 。
5 , [3,4,5] 。
3 , [4,5], 5 10 。
5 , [3,4], 4 9 。
, 5 , true 。
def stoneGame(piles):
n = len(piles)
dp = piles[:]
for d in range(1, n):
for i in range(n - d):
dp[i] = max(piles[i] - dp[i + 1], piles[i + d] - dp[i])
# print(dp)
print(dp[0])
stoneGame([5,3,4,5])