第十二届蓝桥杯真题Java B组 【砝码称重】

该博客介绍了一种使用动态规划方法解决砝码称重问题的算法。通过建立状态转移方程,确定每个砝码放置的三种状态:不放、放左边或放右边,从而计算出所有可能的重量组合。博主给出了完整的Java代码实现,并最终输出了能够用砝码称出的重量种类数。
摘要由CSDN通过智能技术生成

题目描述
题目描述
思路:
采用动态规划(DP),找到状态转移方程就很好解了。对于每个砝码的放置有3种状态:
不放:isOk[i][j] = isOk[i-1][j] (结果为前i-1个是否能称出重量j)
放一边:isOk[i][j] = isOk[i-1][j-w[i]] (结果为前i-1个是否能称出j减去当前砝码重量j)
放另一边:isOk[i][j] = isOk[i-1][j+w[i]] (结果为前i-1个是否能称出j+当前砝码重量j)
这样可以得到状态转移方程:
isOk[i][j] = isOk[i-1][j] || isOk[i-1][j-w[i]] || isOk[i-1][j+w[i]]
要使isOk[0][0]和isOk[i][0]为true,这样之后j-w[i]=0时,才能使isOk[i-1][j-w[i]]为真。
完整代码:

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        boolean[][] isOk = new boolean[102][100003];    //  isOk[i][j]表示前i个砝码是否能称出j重量
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] w = new int[102];     //  各个砝码的重量
        int sum = 0;                //  砝码的和
        for (int i=1;i<=n;i++){
            w[i] = sc.nextInt();
            sum += w[i];
        }
        isOk[0][0] = true;      //  要使0,0的值为true,辅助isOk[i][j]的计算
        for (int i=1;i<=n;i++){
            for (int j=0;j<=sum;j++){   //  isOk[i][0]d的值也必须为0,道理同上
                isOk[i][j] = isOk[i-1][j]||isOk[i-1][Math.abs(j-w[i])]||isOk[i-1][Math.abs(j+w[i])];
            }
        }
        int res = 0;
        for (int j=1;j<=sum;j++){   //  计算有多少种重量
            if (isOk[n][j])
                res++;
        }
        System.out.println(res);
    }
}
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Easenyang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值