题意
给出 n 个数,进行 m 轮判断。每一轮去掉最多三个数,问从剩下的数中选恰好10个数的和恰好是87。
思路
bitset暴力01背包。
题目链接
http://acm.hdu.edu.cn/showproblem.php?pid=5890
AC代码
#include<cstdio>
#include<iostream>
#include<bitset>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 60;
int T, n, m;
int A[maxn];
int ans[maxn][maxn][maxn];
bitset<90> dp[11];
bool Judge(int a, int b, int c)
{
for(int i = 0; i <= n; i++) dp[i].reset();
dp[0][0] = 1;
for(int i = 1; i <= n; i++)
{
if(i == a || i == b || i == c) continue;
for(int j = 10; j >= 1; j--)
dp[j] |= dp[j-1] << A[i];
}
return dp[10][87];
}
int main()
{
scanf("%d", &T);
while(T--)
{
memset(ans, 0, sizeof ans);
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++)
if(Judge(i, j, k)){
ans[i][j][k]=ans[i][k][j]=1;
ans[j][i][k]=ans[j][k][i]=1;
ans[k][i][j]=ans[k][j][i]=1;
}
}
}
scanf("%d", &m);
while(m--)
{
int a, b, c;
scanf("%d %d %d", &a, &b, &c);
if(ans[a][b][c]) puts("Yes");
else puts("No");
}
}
return 0;
}