dp(十一)求组成aim的最少货币数(兑换零钱)&& 最少的完全平方数 && 装箱问题

文章介绍了三个使用动态规划解决的数学问题:如何用最少的硬币组合成目标金额、找到最少个数的完全平方数之和等于给定数,以及在限定容量下装箱以使箱子剩余空间最小。这些问题都涉及到寻找最优解并采用O(n*aim)的时间复杂度和适当的空间复杂度来求解。
摘要由CSDN通过智能技术生成

 

目录

兑换零钱_牛客题霸_牛客网

最少的完全平方数_牛客题霸_牛客网

装箱问题_牛客题霸_牛客网



求组成aim的最少货币数。

描述

给定数组arr,arr中所有的值都为正整数且不重复。每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个aim,代表要找的钱数,求组成aim的最少货币数。

如果无解,请返回-1.

数据范围:数组大小满足 0≤n≤100000≤n≤10000 , 数组中每个数字都满足 0<val≤100000<val≤10000,0≤aim≤50000≤aim≤5000

要求:时间复杂度 O(n×aim)O(n×aim) ,空间复杂度 O(aim)O(aim)。

输入描述:

第一行给定两个正整数分别是 n 和 aim 分别表示数组 arr 的长度和要找的钱数。

第二行给定 n 个正整数表示 arr 数组中的所有元素

输出描述:

输出组成 aim 的最少货币数

组成aim的最少货币数,初始化dp数组为(aim+1, aim+1)  dp[0] = 1;

#include <iostream>
using namespace std;
#include<vector>

int main() {
    int n, aim;
    cin>>n>>aim;
    int *arr = new int[n];
    for(int i = 0; i < n; i++)
        cin>>arr[i];
    if(aim <1)
    {
        cout<<0<<endl;
        return 0;
    }
    vector<int> dp(aim+1, aim+1);
    dp[0] = 0;  // 注意dp数组的初始化  与dp[0]的初始化
    for(int i = 0; i < n; i++)
    {
        for(int j = arr[i]; j <= aim; j++)
        {
            dp[j] = min(dp[j], dp[j-arr[i]]+1);
        }
    }
    if(dp[aim]==aim+1)
        cout<<-1<<endl;
    else
        cout<<dp[aim]<<endl;

    delete[]arr;
    return 0;
}
// 64 位输出请用 printf("%lld")

最少的完全平方数

描述

给定一个正整数n,请找出最少个数的完全平方数,使得这些完全平方数的和等于n。

完全平方指用一个整数乘以自己例如1*1,2*2,3*3等,依此类推。若一个数能表示成某个整数的平方的形式,则称这个数为完全平方数。例如:1,4,9,和16都是完全平方数,但是2,3,5,8,11等等不是

数据范围:1≤n≤104​1≤n≤104​

输入描述:

仅一行,输入一个正整数 n 

输出描述:

按题目要求输出完全平方数之和为n的最少个数

#include <iostream>
using namespace std;
#include<vector>

int main() {
    int n;
    cin>>n;

    vector<int>dp(n+1, n+1);
    dp[0] = 0;
    for(int i = 1; i*i <= n; i++)
    {
        for(int j = i*i; j <= n; j++)
        {
            dp[j] = min(dp[j], dp[j-i*i]+1);
        }
    }
    cout<<dp[n];
    return 0;
}
// 64 位输出请用 printf("%lld")

装箱问题_牛客题霸_牛客网

描述

有一个箱子容量为 V ,同时有n个物品,每个物品有一个体积(正整数)。每个物品只能使用一次。

要求n个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。

数据范围: 1≤V≤2×104 1≤V≤2×104  , 1≤n≤30 1≤n≤30  ,每个物品的体积满足 1≤numi≤2×104 1≤numi​≤2×104 

输入描述:

第一行输入一个正整数 V 表示箱子的容量,

第二行输入一个正整数 n 表示物品的个数。

后续 n 行每行输入一个正整数表示物品的体积    

输出描述:

输出箱子最小剩余空间

#include <iostream>
#include <linux/limits.h>
using namespace std;
#include<vector>

int main() 
{
    int V, n;
    cin>>V>>n;
    vector<int> things(n);
    for(int i = 0; i < n; i++)
        cin>>things[i];
    vector<int> dp(V+1);
    for(int i = 0; i < n; i++)
    {
        for(int j = V; j >= things[i]; j--)
        {
            dp[j] = max(dp[j], dp[j-things[i]]+things[i]);
        }
    }
    int l = V-dp[V];
    cout<<l<<endl;
    return 0;
}
// 64 位输出请用 printf("%lld")
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值