蓝桥杯2021年第十二届省赛真题-砝码称重 - C语言网 (dotcpp.com)
你有一架天平和 N 个砝码,这 N 个砝码重量依次是 W1, W2, · · · , WN。
请你计算一共可以称出多少种不同的重量?
注意砝码可以放在天平两边。
可以使用DP将dp[i][j]表示只从前i个物品中选,且总重量为j的方案的集合,其属性是是否选用(bool)
一共有三种方案
方案一:不选第i个物品
方案二:将第i个物品加上(将第i个物品放在右边)
方案三:将第i个物品减去(将第i个物品减去)
注:为了防止减去第i个物品数组的标号为负数,需要加上一个值,使之始终为正数
- #include
- using namespace std;
- const int N = 110, M = 200010, b = M / 2;
- int n, m, ans, w[N], dp[N][M];
- int main()
- {
- cin >> n;
- for(int i = 1; i <= n; i ++)
- {
- cin >> w[i];
- m += w[i];
- }
- dp[0][b] = 1;
- for(int i = 1; i <= n; i ++)
- {
- for(int j = -m; j <= m; j ++)
- {
- dp[i][j + b] = dp[i - 1][j + b];
- if(j - w[i] >= -m)dp[i][j + b] |= dp[i - 1][j - w[i] + b];
- if(j + w[i] <= m)dp[i][j + b] |= dp[i - 1][j + w[i] + b];
- }
- }
- for(int i = 1; i <= m; i ++)
- {
- if(dp[n][i + b] == 1)ans ++;
- }
- cout << ans;
- return 0;
- }