目标和
题目描述
给你一个整数数组 a 和一个整数 t 。
向数组中的每个整数前添加 ‘+’ 或 ‘-’ ,然后串联起所有整数,可以构造一个 表达式 :
例如,a = {2, 1} ,可以在 2 之前添加 ‘+’ ,在 1 之前添加 ‘-’ ,然后串联起来得到表达式 “+2-1” 。
输出 通过上述方法构造的、运算结果等于 t 的不同 表达式 的数目。
输入格式
第一行,n
第二行,数组 a 的 n 个整数
第三行,t
输出格式
结果等于 t 的 表达式 数目
样例
输入样例:
5
1 1 1 1 1
3
输出样例:
5
样例解释: 一共有 5 种方法让最终目标和为 3 。
-1 + 1 + 1 + 1 + 1 = 3
+1 - 1 + 1 + 1 + 1 = 3
+1 + 1 - 1 + 1 + 1 = 3
+1 + 1 + 1 - 1 + 1 = 3
+1 + 1 + 1 + 1 - 1 = 3
数据范围与提示
1 <= n <= 20
0 <= a[i] <= 1000
0 <= a数组所有元素之和 <= 1000
-1000 <= t <= 1000
解题分析
这道题可理解为:枚举n个位置上运算符(+或-),可转换为枚举n个0或1(二进制数 00…00 ~ 11…11),即十进制整数0 ~ 2 n − 1 2^n-1 2n−1。
int main() {
int n;
cin>>n;
int a[20];
for (int i = 0; i < n; i++)
cin>>a[i];
int t;
cin>>t;
int s = 0;
for (int i = 0; i < (1 << n); i++) { // 整数i:0 ~ 2^n - 1。 (1 << n) 表示 2^n
bitset<20> b(i); // 将i转换为二进制数b:00...00 ~ 11...11
int w = 0;
for (int j = 0; j < n; j++) {
if (b[j] == 0) // 0表示-号
w = w - a[j];
else // 1表示+号
w = w + a[j];
}
if (w == t)
s++;
}
cout << s;
return 0;
}