题目链接:[蓝桥杯 2021 省 AB] 砝码称重 - 洛谷
思路:
维护f数组,f[i]=true 代表 i 可以称出来。
现将天平分为物品盘和砝码盘
当放一个重量为m的砝码
遍历所有可能的重量,若某重量w可以被表示,则分为一下几种情况
1.w+m也可以被表示(将w和m都放到砝码盘)
2.若w > m ,那么 w-m 也可以被表示(将m放到物品栏,w放到砝码盘)
3.若w < m,那么m-w 也可以被表示 (将m放到砝码盘,w放到物品盘)
注意点:由于每个重量的砝码只有一个,所以在处理一个砝码时只能更新一次,可以用二维数组表示f,记录上一层f的状态
这里用队列记录需要更新的重量,当遍历结束后,统一更新
代码:
#include<iostream>
#include<queue>
#include<cmath>
using namespace std;
const int N = 100005;
int n;
bool f[N];
int ans;
int a;
queue<int>q;
int main()
{
cin>>n;
f[0]=true;
for(int i=1;i<=n;++i)
{
cin>>a;
for(int j=0;j<N;++j)
{
if(f[j])
{
q.push(abs(j-a));
if(j+a<N) q.push(j+a);
}
}
while(!q.empty())
{
f[q.front()]=true;
q.pop();
}
}
for(int i=1;i<N;++i) if(f[i]) ans++;
cout<<ans<<endl;
return 0;
}