砝码称重 (背包问题,做2次)(蓝桥杯)

 

 

思路:

首先正向的把能够组合在一起的数弄出来(直接加的那种,背包)

对于减法, 就利用之前弄出来的数作为初始值,选出一些数来减到掉就可以了(背包的思想),(相同的砝码出现在左右2边会被约掉的,所以没关系)

#include <bits/stdc++.h>
using namespace std;
#define ri register int 
#define M 100005

template <class G> void read(G &x)
{
    x=0;int f=0; char ch=getchar();
    while(ch<'0'||ch>'9'){f|=ch=='-';ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    x=f?-x:x;
    return ;
} 

bool f[M];
int n,val[M];
int m;
int main(){
    
    read(n);
    for(ri i=1;i<=n;i++) 
    {
    read(val[i]);m+=val[i];
    }
    
    f[0]=1;
    for(ri i=1;i<=n;i++)
    {
        for(ri j=m;j>=val[i];j--)
        {
            if(f[j-val[i]]) f[j]=1;
        }
    }
    for(ri i=1;i<=n;i++)
    {
        for(ri j=val[i];j<=m;j++)
        {
            if(f[j]) f[j-val[i]]=1;
        }
    }
    long long ans=0;
    for(ri i=1;i<=m;i++)
    {
       if(f[i]) ans++;    
    }
    printf("%lld",ans);
    return 0;
    
}
View Code

 

posted @ 2022-03-31 15:57  VxiaohuanV  阅读(54)  评论(0编辑  收藏  举报