【蓝桥杯】历届真题 砝码称重(省赛)Java

资源限制

内存限制:256.0MB   C/C++时间限制:1.0s   Java时间限制:3.0s   Python时间限制:5.0s

问题描述

        你有一架天平和N个砝码,这N个砝码重量依次是W1,W2,.… . , Wn 。请你计算一共可以称出多少种不同的重量?

注意砝码可以放在天平两边。

输入格式

        输入的第一行包含一个整数N。

        第二行包含N个整数:W1,W2,W3,… ,Wn 。

输出格式

        输出一个整数代表答案。

样例输入

        3

        1        4        6

样例输出

        10

样例说明

        能称出的10种重量是:1、2、3、4、5、6、7、9、10、11。

        1 = 1;

        2=6-4(天平一边放6,另一边放4);

        3=4- 1;

        4=4;

        5=6-1;

        6=6;

        7=1+6;

        9=4+6-1;

        10=4+6;

        11=1+4+6

评测用例规模与约定

        对于50%的评测用例,1≤N≤15。

        对于所有评测用例,1≤N ≤ 100,N个砝码总重不超过100000。

思路与分析

        该题初看没什么头绪,但仔细读题并结合数据结构的相关知识便可以发现制胜之道。利用该题所给的题例,我自然而然的联想到了——动态规划法。

        而动态规划法解题的关键是什么?对,状态转移方程。只需要根据所给题例解析出背后的“规律”,也就是方程即可。

        理清思路,开始解题。
        首先,我们要明确砝码有几种状态【w:重量首字母】

                1、放在左边:arr[i][j] = arr[i-1][j-w[i]] (前i-1个砝码是否能称出j-当前砝码重量   j)

                2、放在右边:arr[i][j] = arr[i-1][j+w[i]](前i-1个砝码是否能称出j+当前砝码重量  j)

                3、不进行放置:arr[i][j] = arr[i-1][j]    (前i-1个砝码是否能称出重量  j)

        由上述式子可得状态转移方程如下:

                arr[i][j] = arr[i-1][j-w[i]] || arr[i][j] = arr[i-1][j+w[i]]  || arr[i][j] = arr[i-1][j]

        不难发现,该式子要想使得 arr[i-1][j-w[i]] 为 true,首先要让arr[0][0] 及 arr[i][0] 为 true,这样在 j-w[i]=0 时,arr[i-1][j-w[i]] 才能为 true。

代码

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        //arr[i][j]表示前i个砝码是否能称出重量j
        boolean[][] arr = new boolean[102][100003];    //100003 3代表3种状态
        Scanner sc = new Scanner(System.in);
        int num = sc.nextInt();
        int[] w = new int[102];     //该数组用于存放各个砝码的重量
        int sum = 0;                //砝码数量和
        for (int i=1;i<=num;i++){
            w[i] = sc.nextInt();
            sum += w[i];
        }
        arr[0][0] = true;      //arr[0][0]的值为true,意为帮助arr[i][j]计算
        for (int i=1;i<=n;i++){
            for (int j=0;j<=sum;j++){   //arr[i][0]的值也必须为0
                arr[i][j] = arr[i-1][j]||arr[i-1][Math.abs(j-w[i])]||arr[i-1][Math.abs(j+w[i])];
            }
        }
        int res = 0;    //存储结果数
        for (int j=1;j<=sum;j++){   
            if (arr[num][j])    //能测到这个重量
                res++;    //结果++
        }
        System.out.println(res);
    }
}

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
社会演员多的头像社会演员多普通用户
上一篇 2023年12月13日
下一篇 2023年12月13日

相关推荐