砝碼稱重 (揹包問題,做2次)(藍橋杯)
阿新 • • 發佈:2022-03-31
思路:
首先正向的把能夠組合在一起的數弄出來(直接加的那種,揹包)
對於減法, 就利用之前弄出來的數作為初始值,選出一些數來減到掉就可以了(揹包的思想),(相同的砝碼出現在左右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>'View Code9'){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; }