题意:给出n个数字,去掉其中不超过3个,问能否在剩下的数字中挑出10个使得和为87。
暴力+bitset优化
用 f[i][j][k] 表示去掉第 i , j , k 个能否满足,在剩下的数中用 bitset<88> s[i] 表示取 i 个数能构成什么数字,转移就好了。
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <bitset>
using namespace std;
#define maxn 55
typedef long long LL;
int a[maxn], f[maxn][maxn][maxn];
bitset<90> s[11];
int n;
bool solve(int x, int y, int z){
for (int i = 0; i < 11; i++) s[i].reset();
s[0][0] = 1;
for (int i = 1; i <= n; i++) {
if (i == x || i == y || i == z || a[i] > 87) continue;
for (int j = 10; j > 0; j--) {
s[j] |= s[j - 1] << a[i];
}
}
if (s[10][87]) return 1;
else return 0;
}
int main() {
int T;
scanf("%d", &T);
while (T--) {
scanf("%d", &n);
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
for (int i = 1; i <= n; i++){
for (int j = i; j <= n; j++){
for (int k = j; k <= n; k++){
f[i][j][k] = solve(i, j, k);
}
}
}
int q;
scanf("%d", &q);
while (q--) {
int b[3];
scanf("%d%d%d", &b[0], &b[1], &b[2]);
sort(b, b+3);
if (f[b[0]][b[1]][b[2]]) printf("Yes\n");
else printf("No\n");
}
}
}