题解 | #称砝码#DP

称砝码

https://www.nowcoder.com/practice/f9a4c19050fc477e9e27eb75f3bfd49c

import java.math.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
import java.util.stream.*;
import java.util.regex.*;
import java.util.function.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);

        int n = in.nextInt();
        int[] m = new int[n];
        for (int i = 0; i < n; i++) {
            m[i] = in.nextInt();
        }

        int total = 0;
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            int count = in.nextInt();
            for (int j = 0; j < count; j++) {
                list.add(m[i]);
            }
        }

        // timeout
        // Set<Integer> ways = new HashSet<>();
        // move(list, 0, new ArrayList<>(), ways);
        // System.out.println(ways.size());

        // DP
        Set<Integer>[] d = new Set[list.size() + 1];
        d[0] = new HashSet<>(Arrays.asList(new Integer[] {0}));
        for (int i = 1; i < list.size() + 1 ; i++) {
            Integer curr = list.get(i - 1);

            // 使用砝码
            Set<Integer> newSet = d[i - 1].stream()
                                  .mapToInt(a-> a + curr).boxed()
                                  .collect(Collectors.toCollection(HashSet::new));
            // 不使用砝码
            newSet.addAll(d[i - 1]);

            d[i] = newSet;
        }
        System.out.println(d[list.size()].size());
    }

    // 超时
    static void move(List<Integer> list, int step, List<Integer> way,
                     Set<Integer> ways) {
        if (step == list.size()) {
            ways.add(way.stream().mapToInt(Integer::intValue).sum());
            return;
        }

        // 2 ways
        move(list, step + 1, new ArrayList<>(way), ways);
        List<Integer> newWay = new ArrayList<>(way);
        newWay.add(list.get(step));
        move(list, step + 1, newWay, ways);
    }
}


全部评论

相关推荐

在笔试的大西瓜很矫健:校招数分不用想了,这经历和学历都不够用,大厂更别想,初筛都过不了,说点不好听的小厂数分都进不去(小厂也是假数分),要两个对口实习+3个项目(或者3+2),而且要有含金量才能补一点你的学历劣势。 建议刷实习,社招找数分,校招看运气,能入行业就行,可以运营转数分
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务