题目描述
给定数组arr,arr中所有的值都为正整数且不重复。每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个aim,代表要找的钱数,求组成aim的最少货币数。
输入描述
输入包括两行,第一行两个整数n(0<=n<=1000)代表数组长度和aim(0<=aim<=5000),第二行n个不重复的正整数,代表ARR(1<=ARRi<=10^9)。
输出描述
输出一个整数,表示组成aim的最小货币数,无解时输出-1.
示例1
输入:
3 20
5 2 3
输出:
4
说明:
20 = 5 * 4
示例2
输入:
3 0
5 2 3
输出:
0
示例3
输入:
2 2
3 5
输出:
-1
备注
时间复杂度O(n*aim),空间复杂度O(n)。
解题思路
该题目可以转换为完全背包问题求解。
aim -------------- 背包的容量
每种货币的面值---------------每种物品的体积
货币数-----------------每种物品的价值
即:
求背包容量为aim的最小价值。每种物品的价值都是1。
实现代码
/*
* @Description: 换钱的最少货币数
* @Author:
* @Date: 2020-10-26 15:30:58
* @LastEditTime: 2020-10-26 20:17:08
* @LastEditors: Please set LastEditors
*/
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int MAX = 99999;//直接使用INT_MAX会报错
int main()
{
int n, aim;
cin >> n >> aim;
if (aim <= 0 || n == 0)
{
return -1;
}
vector<int> dp(aim + 1, MAX);
dp[0] = 0;
int money;
for (int i = 1; i <= n; i++)
{
cin >> money;
for (int j = money; j <= aim; j++)
{
dp[j] = min(dp[j], dp[j - money] + 1);//关键代码
}
}
cout << (dp[aim] == MAX ? -1 : dp[aim]) << endl;
//system("pause");
return 0;
}