题解 | 称砝码

称砝码

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

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
    scanner := bufio.NewScanner(os.Stdin)
    scanner.Scan()
    kindStr := scanner.Text()
    kind, _ := strconv.Atoi(kindStr)
    scanner.Scan()
    weightsStr := strings.Fields(scanner.Text())
    weights := make([]int, kind)
    for idx, _ := range weightsStr {
        weights[idx],_ = strconv.Atoi(weightsStr[idx])
    }
    scanner.Scan()
    countsStr := strings.Fields(scanner.Text())
    counts := make([]int, kind)
    for idx, _ := range countsStr {
        counts[idx],_ = strconv.Atoi(countsStr[idx])
    }
    noZeroKind := uniqueWeights(weights, counts)
    fmt.Print(noZeroKind+1)
}

// uniqueWeights 用于计算可以称出的不同重量的个数
// weights: 每种砝码的重量
// counts: 每种砝码的个数
func uniqueWeights(weights []int, counts []int) int {
	// 使用 map 模拟一个动态规划数组 dp,key 表示当前可以称出的重量
	dp := make(map[int]bool)
	dp[0] = true // 初始状态,表示什么都不放时,重量为 0

	// 遍历每种砝码
	for i := 0; i < len(weights); i++ {
		w := weights[i] // 当前砝码重量
		c := counts[i]  // 当前砝码个数

		// 用于临时存储当前砝码可能组合出来的新重量
		cur := make(map[int]bool)

		// 遍历当前所有已知的可达重量
		for weight := range dp {
			// 尝试放 1 到 c 个当前砝码
			for k := 1; k <= c; k++ {
				newWeight := weight + w*k
				cur[newWeight] = true // 将新重量加入当前回合
			}
		}

		// 把当前回合新得到的重量合并到 dp 中
		for k := range cur {
			dp[k] = true
		}
	}

	// 删除 0 重量(不放任何砝码)
	delete(dp, 0)

	// 剩下的 key 就是所有不同的正整数重量
	return len(dp)
}

全部评论

相关推荐

牛客383479252号:9,2学生暑期实习失利开始投小厂,给这群人整自信了
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

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