算法题——01背包——200915

题目

1. 简单的烦恼

链接:https://ac.nowcoder.com/acm/problem/25184
来源:牛客网

  • 题目描述 网易云音乐推出了定时关闭播放的功能,假设到了定时关闭播放的时间,当前这首歌还没有播放完,那就把它播放完关闭;如果到了定时关闭的时间,当前歌恰好播放完,那就立即关闭。xrc在知道网易云这个算法后,想知道如果自己定时 t 时间后关闭播放,那最多能听多长时间的歌,已知 xrc 歌单中一共有 n
    首歌,并且知道每首歌的播放时间分别是 a[i]。

  • 输入描述: * 第一行一个整数T(T <= 23),表示数据组数。

    • 在每组输入数据中,第一行有两个正整数,n(n <= 200), t(t <=
      80000),分别表示歌单中歌曲的数目,和题目描述中的t。

    • 第二行中有n个正整数a[i](a[i] <= 400),表示每首歌曲的时间长度。

  • 输出描述: 对于每组数据,输出一个ans,表示最多能听多长时间的歌曲。

  • 示例1 输入 1 3 7 4 3 2 输出 9

  • 说明 先听第2首歌和第3首歌,最后播放第1首歌,在7单位时间后,第3首歌还没有播放完,所以要等第1首歌播放完,共能听9单位时间的歌。

2. 货币系统

链接:
https://ac.nowcoder.com/acm/problem/21467
来源:牛客网

题目描述

  • 在网友的国度中共有n种不同面额的货币,第i种货币的面额为a[i],你可以假设每一种货币都有无穷多张。为了方便,我们把货币种数为n、面额数组为a[1…n]的货币系统记作(n,a)。
  • 在一个完善的货币系统中,每一个非负整数的金额x 都应该可以被表示出,即对每一个非负整数x,都存在n个非负整数t[i] 满足a[i] x t[i] 的和为x。然而,在网友的国度中,货币系统可能是不完善的,即可能存在金额x不能被该货币系统表示出。例如在货币系统n=3,
    a=[2,5,9]中,金额1,3就无法被表示出来。
  • 两个货币系统(n,a)和(m,b)是等价的,当且仅当对于任意非负整数x,它要么均可以被两个货币系统表出,要么不能被其中任何一个表出。 现在网友们打算简化一下货币系统。他们希望找到一个货币系统(m,b),满足(m,b)
    与原来的货币系统(n,a)等价,且m尽可能的小。他们希望你来协助完成这个艰巨的任务:找到最小的m。
  • 输入描述: 输入的第一行包含一个整数T,表示数据组数。接下来按照如下格式分别给出T组数据。 每组数据的第一行包含一个正整数n。接下来一行包含n个由空格隔开的正整数a[i]。
  • 输出描述: 输出文件共T行, 对于每组数据, 输出一行一个正整数, 表示所有与(n, a)等价的货币系统(m, b)中, 最小的m。
  • 示例1 输入: 2 4 3 19 10 6 5 11 29 13 19 17 输出: 2 5
  • 说明 在第一组数据中,货币系统(2, [3,10])和给出的货币系统(n, a)等价,并可以验证不存在m < 2的等价的货币系统,因此答案为2。 在第二组数据中,可以验证不存在m < n的等价的货币系统,因此答案为5。
  • 备注: 1 <= T <= 20, 1 <= n <= 100, 1 <= a[i] <= 25000

3. 音量调节

链接:https://ac.nowcoder.com/acm/problem/19990

  • 题目描述
    一个吉他手准备参加一场演出。他不喜欢在演出时始终使用同一个音量,所以他决定每一首歌之前他都要改变一次音量。在演出开始之前,他已经做好了一个列表,里面写着在每首歌开始之前他想要改变的音量是多少。每一次改变音量,他可以选择调高也可以调低。
  • 音量用一个整数描述。输入文件中给定整数beginLevel,代表吉他刚开始的音量,以及整数maxLevel,代表吉他的最大音量。音量不能小于0也不能大于maxLevel。输入文件中还给定了n个整数c1,c2,c3……cn,表示在第i首歌开始之前吉他手想要改变的音量是多少。
  • 吉他手想以最大的音量演奏最后一首歌,你的任务是找到这个最大音量是多少。 * 链接:https://ac.nowcoder.com/acm/problem/19990 来源:牛客网
  • 输入描述: 第一行依次为三个整数:n, beginLevel, maxlevel。 第二行依次为n个整数:c1,c2,c3……cn。
  • 输出描述: 输出演奏最后一首歌的最大音量。如果吉他手无法避免音量低于0或者高于maxLevel,输出-1。
  • 示例1 输入: 3 5 10 5 3 7 输出: 10

4. 分割等和子集

链接:https://leetcode-cn.com/problems/partition-equal-subset-sum

给定一个只包含正整数的非空数组。是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。

  • 注意:
    每个数组中的元素不会超过 100 数组的大小不会超过 200

  • 示例 1:
    输入: [1, 5, 11, 5]
    输出: true
    解释: 数组可以分割成 [1, 5, 5] 和 [11].

  • 示例 2:
    输入: [1, 2, 3, 5]
    输出: false
    解释: 数组不能分割成两个元素和相等的子集.

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/partition-equal-subset-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

总结

  • 要注意数组的顺序能不能打乱。以及是否可以重复使用,可以重复使用(完全背包)、不能重复使用(01背包)
    • 譬如1.简单的烦恼 听歌顺序可以打乱,但是每首歌只能听一次。
    • 2.货币系统:顺序可以打乱,对它进行排序,因为大货币能由小货币组成,不能由更大的货币组成,因此先判断最大的货币,比较简单。
    • 3.音量调节:顺序不能打乱,每首歌只能出现一次。
  • 注意每次选择之间是否有记忆化:
    • 1.听歌,因为每首歌只能出现一次,如果从0开始刷新,那么前面可能会出现一首歌不止出现一次。这时候,从后面开始刷新,则比较简单。
    • 2.货币之间显然没有影响
    • 3.前面的音量决定了后面的音量变化。这题也可以用回溯,但因为音量范围有限,动态刷新效率更高。

解答

1. 简单的烦恼

public class NC25184 {
   
   
    public static void main(String[] args) {
   
   
        Scanner in = new Scanner(System.in);
        int N = in.nextInt();
        for (int i = 0; i < N; i++) {
   
   
            int n = in.nextInt();
            int t = in.nextInt();
            int[] a = new int[n];
            for (int j = 0; j < n; j++) {
   
   
                a[i] = in.nextInt();
            }
            Arrays.sort(a);
            System.out.println(maxSumOfSong(a,t-1,a.length-1)+a[a.length-1]);
        }
    }
    public static int maxSumOfSong(int[] a, int t,int end
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值