先来道简单的
P2347 [NOIP1996 提高组] 砝码称重
用 f [ i ] 来表示重量为 i 的物品能否被称出 存的是bool值
i循环是遍历每种砝码 , j 则是遍历该种砝码的使用个数
k从大到小往下遍历 如果 重量为k的物品能称出来 那么加上w [ i ] 也能称出来其实bool数组该开大一点防止越界 但我这样也过了,,,数据比较弱
从大到小遍历k是因为从小到大的话加过一次 w [ i ] 后在后面又会遇到一次 那同一个砝码你用了两次肯定是不行的
#include <bits/stdc++.h>
using namespace std;
int sum;
int a[7];
int w[7]={0,1,2,3,5,10,20};
bool f[1001];
int main()
{
for(int i = 1; i <= 6; i ++) cin >> a[i];
f[0] = 1; //一个砝码也不用的情况虽然不算,也要先初始化成1
for(int i = 1; i <= 6; i ++)
{
for(int j = 1; j <= a[i]; j ++)
{
for(int k = 1000; k >= 0; k --)
{
if(f[k]) f[k + w[i]] = 1;
}
}
}
for(int i = 1; i <= 1000; i ++)
{
if(f[i]) sum++;
}
cout << "Total=" <<sum;
return 0;
}
P8742 [蓝桥杯 2021 省 AB] 砝码称重
用 f [ i ] [ j ] 来表示只用前 i 个 砝码 能否称出重量 j ,存的是bool值
状态计算:
想要用前 i 个砝码称出重量 j 有三种情况
第一种:不使用第 i 个砝码 ,即只用前 i - 1 个砝码就能称出 j
第二种:把砝码放在更重的一侧,要让这种方法成立的话,就代表 只用前i - 1 个砝码就能够称出重量为abs ( j - w [ i ] )的物体,因为能够称出这个重量的话,只要把 砝码 i 放在更重的一侧 就能称出重量 j 了
第三种:把砝码放在更轻的一侧,他等于 要只用前 i - 1 个砝码称出 j + w [ i ] 那么放在更轻的一侧相当于减去 w [ i ] ,就能够称出 j 了
三种有任意一种为true,f [ i ] [ j ] 就为true
#include <bits/stdc++.h>
using namespace std;
int N,sum,ans;
int w[105];
bool f[105][200005];
int main()
{
cin >> N;
for(int i = 1; i <= N; i ++) cin >> w[i], sum += w[i]; //算出总重
f[0][0] = 1; //为了状态计算,重量为0 也能称出
for(int i = 1; i <= N; i ++)
{
for(int j = 0; j <= sum; j ++)
{
f[i][j] = (f[i-1][j] || f[i-1][j+w[i]] || f[i-1][abs(j-w[i])]);
}
}
for(int i = 1; i <= sum; i ++)
{
if(f[N][i]) ans++;
}
cout << ans;
return 0;
}