1.给定数组arr,arr中所有的值都是正数且不重复。每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个整数aim代表要找的钱数,求组成aim的最少货币数。
方法一:
第一列都为0,第一行表示只能使用arr[0]货币的情况下找某个钱数的最小张数,之后的位置依次从左到右,再从上到下计算,比较dp[i-1][j]和dp[i][j-arr[0]]+1的值,选较小的,上一行的数是可以找开的张数。
#coding=utf-8
def solution(nums,aim):
if len(nums)==0 or aim<0:
return -1
n=len(nums)
m=float('Inf')
dp=[[0 for i in range(aim+1)] for j in range(len(nums))]
for i in range(1,aim+1):
dp[0][i]=m
if i-nums[0]>=0 and dp[0][i-nums[0]]!=m:
dp[0][i]=dp[0][i-nums[0]]+1
left=0
for i in range(1,n):
for j in range(1,aim+1):
left=m
if j-nums[i]>=0 and dp[i][j-nums[i]]!=m:
left=dp[i][j-nums[i]]+1
dp[i][j]=min(left,dp[i-1][j])
if dp[n-1][aim]!=m:
return dp[n-1][aim]
else:
return -1
方法二: 空间压缩法,参考矩阵的最小路径和
#coding=utf-8
class Solution(object):
def coinChange(self,nums,aim):
if len(nums)==0 or aim<0:
return -1
n=len(nums)
m=float('Inf')
dp=[0 for i in range(aim+1)]
for i in range(1,aim+1):
dp[i]=m
if i-nums[0]>=0 and dp[i-nums[0]]!=m:
dp[i]=dp[i-nums[0]]+1
left=0
for i in range(1,n):
for j in range(1,aim+1):
left=m
if j-nums[i]>=0 and dp[j-nums[i]]!=m:
left=dp[j-nums[i]]+1
dp[j]=min(left,dp[j])
if dp[aim]!=m:
return dp[aim]
else:
return -1
- 给定数组arr,arr中所有的值都为正数,每个值仅代表一张钱的面值,再给定一个整数aim代表要找的钱数,求组成aim的最少货币数。
直接是压缩空间以后的动态规划
#coding=utf-8
class Solution(object):
def coinChange(self,nums,aim):
if len(nums)==0 or aim<0:
return -1
m=float('Inf')
dp=[0 for i in range(aim+1)]
for i in range(1,aim+1):
dp[i]=m
if nums[0]<=aim:
dp[nums[0]]=1
for i in range(1,len(nums)):
for j in range(aim,0,-1):
leftup=m
if j-nums[i]>=0 and dp[j-nums[i]]!=m:
leftup=dp[j-nums[i]]+1
dp[j]=min(leftup,dp[j])
if dp[aim]!=m:
return dp[aim]
else:
return -1
3.牛客上的题目
给定一个有n个正整数的数组A和一个整数sum,求选择数组A中部分数字和为sum的方案数。
当两种选取方案有一个数字的下标不一样,我们就认为是不同的组成方案。
输入描述:
输入为两行:
第一行为两个正整数n(1 ≤ n ≤ 1000),sum(1 ≤ sum ≤ 1000)
第二行为n个正整数Ai,以空格隔开。
输出描述:
输出所求的方案数
示例1
输入
5 15
5 5 10 2 3
输出
4
#coding=utf-8
while True:
try:
f=map(int,raw_input().strip().split())
A=map(int,raw_input().strip().split())
n=f[0];target=f[1]
res=[[0 for i in range(target+1)] for j in range(n)]
if A[0]<=target:
res[0][A[0]]=1
for i in range(1,n):
for j in range(1,target+1):
res[i][j]+=res[i-1][j]
if j-A[i]>=1:
res[i][j]+=res[i-1][j-A[i]]
if j==A[i]:
res[i][j]+=1
print res[n-1][target]
except:
break