【洛谷 8742】[蓝桥杯 2021 省 AB] 砝码称重

题目描述

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

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

输入格式

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

第二行包含 N 个整数: �1,�2,�3,⋯ ,��W1,W2,W3,,WN 。

输出格式

输出一个整数代表答案。

输入输出样例

输入 #1
3
1 4 6
输出 #1
10

说明/提示

【样例说明】

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

1=12=6−4( 天平一边放 6, 另一边放 4) 3=4−14=45=6−16=67=1+69=4+6−110=4+611=1+4+61=12=64( 天平一边放 6, 另一边放 4) 3=414=45=616=67=1+69=4+6110=4+611=1+4+6

【评测用例规模与约定】

对于 50%50% 的评测用例, 1≤�≤151N15 。

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

蓝桥杯 2021 第一轮省赛 A 组 F 题(B 组 G 题)。

 

题解:01背包的变形,统计答案即可

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<bits/stdc++.h>
using namespace std;
int n,sum,ans;
int a[103],dp[10000003];
int main(){
    freopen("2347.in","r",stdin);
    freopen("2347.out","w",stdout);
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        sum+=a[i];
    }
    dp[0]=1; 
    for(int i=1;i<=n;i++)
        for(int j=sum;j>=a[i];j--)
            if(dp[j-a[i]] && !dp[j]) 
               { dp[j]=1; ans++; }
    //若j-a[i]存在,则j一定存在,由j-a[i]加上一个a[i]砝码得来  
    for(int i=1;i<=n;i++)
        for(int j=1;j<=sum-a[i];j++)
            if(dp[j+a[i]] && !dp[j]) 
               { dp[j]=1; ans++; }
    //若j+a[i]存在,则j一定存在,由j+a[i]减去一个a[i]砝码得来 
    printf("%d",ans);
    return 0;
}

 

posted @ 2023-10-25 16:22  #Cookies#  阅读(80)  评论(0编辑  收藏  举报