题目描述
给定数组arr,arr中所有的值都为正整数且不重复。每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个aim,代表要找的钱数,求组成aim的最少货币数。
如果无解,请返回-1.
【要求】
时间复杂度O(n×aim),空间复杂度On。
题解:
经典dp问题
我们考虑一下当然价值x由什么组成?
x可以由上一个状态x-arr[i]加上第i’个货币arr[i]组成
也就是dp[x]=dp[x-arr[i]]+1
这个+1也就是代表多用了一个货币(因为题目问的是最少货币数,所以dp[x]表示的是x元所用的最少货币数)
因为arr有多个,所以dp取最小值(记得dp要初始化为最大,但是dp[0]=0)
dp[j]=min(dp[j],dp[j-arr[i]]+1);
最后如果dp[aim]没被改变(还是最大化),说明无法表示aim,即返回-1
否则返回dp[aim]
代码:
class Solution {
public:
/** * 最少货币数 * @param arr int整型vector the array * @param aim int整型 the target * @return int整型 */
int minMoney(vector<int>& arr, int aim) {
// write code here
if(aim==0)return 0;
vector<int>dp(aim+1,0x3f3f3f);
dp[0]=0;
for(int i=0;i<arr.size();i++)
{
for(int j=arr[i];j<=aim;j++)
{
dp[j]=min(dp[j],dp[j-arr[i]]+1);
}
}
if(dp[aim]==0x3f3f3f)return -1;
else return dp[aim];
}
};