第二十届蓝桥杯c++ B组 砝码称重

这篇博客介绍了如何使用动态规划解决砝码称重问题。通过枚举砝码的选择情况,博主展示了如何计算所有可能的重量组合,并找到了能够达到的正重量总数。代码实现中,利用了或运算来合并不同选择方案,并处理了砝码放在两边的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:砝码称重

题解:

f[i][j]表示选择前i个砝码总重量为j是否可以得到

我们设定砝码放在左边为正,放在右边为负

对于枚举到当前这个砝码,我们有三种选择方案:

1. 不选。则当前状态与上一个状态方案相同,即f[i][j] = f[i-1][j]

2. 选择放在左边。则f[i][j] = f[i-1][j-w[i]]

3. 选择放在右边。则f[i][j] = f[i-1][j+w[i]]。因为放在右边为负的,当前状态为j则上一个状态应该为j+w[i]

在这里j-w[i]会出现负数的情况,但是下标不能为负。不难发现重量为负数的时候和重量为正数的时候应该是相同的,因为重量只能为正,所以计算时取绝对值即可

代码如下:

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 110, M = 1e5 + 7;

int w[N];
bool f[N][M];

int main()
{
    int n, m = 0; scanf("%d", &n);
    for (int i = 1 ; i <= n; i ++ ) scanf("%d", &w[i]), m += w[i];
    f[0][0] = true;
    for (int i = 1 ; i <= n; i ++ )
    {
        for (int j = 0; j <= m; j ++ )
        {
            //或运算,有1则为1
            f[i][j] = f[i - 1][j];
            if (j + w[i] <= m) f[i][j] |= f[i - 1][j + w[i]];
            f[i][j] |= f[i - 1][abs(j - w[i])];
        }
    }
    int ans = 0;
    for (int i = 1; i <= m; i ++ ) if (f[n][i]) ans ++;
    printf("%d\n", ans);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值