给你n(n<=50)个数,m( m<=1e5 )次询问,每次询问给你三个数,问在给出的数里面存不存在任意取10个(不包含这三个数)的数的和刚好为87,每次询问输出Yes/No。
暂时先上代码,交了好几次,基本都卡过去了,但最好也只是902ms(在G++上交)
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<math.h>
#include<queue>
#include<string.h>
#include<algorithm>
#include<bitset>
#define PI acos(-1.0)
using namespace std;
int n,a[60];
bool reco[60][60][60][2]; //记录该3个数是否计算过,是否yes
bool check(int x,int y,int z)
{
if(reco[x][y][z][0]==1) return reco[x][y][z][1];
bitset<90> bs[12];
bs[0][0]=1;
for(int i=1;i<=n;i++)
{ if(*(a+i)>87) continue;
if(i==x||i==y||i==z) continue;
for(int j=10;j>=1;j--)
*(bs+j)|=*(bs+j-1)<<*(a+i);
if(bs[10][87]==1) break;
}
reco[x][y][z][1]=(bs[10][87]==1);
reco[x][y][z][0]=1;
return reco[x][y][z][1];
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
memset(reco,0,sizeof(reco));
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
int q;
scanf("%d",&q);
while(q--)
{
int x[5];
scanf("%d%d%d",x,x+1,x+2);
sort(x,x+3);
if(reco[x[0]][x[1]][x[2]][1]) printf("Yes\n");
else if(check(x[0],x[1],x[2])) printf("Yes\n");
else printf("No\n");
}
}
}
以及AtCoder Grand Contest #020 by tourist C题
链接:https://agc020.contest.atcoder.jp/tasks/agc020_c
AC代码:
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<math.h>
#include<queue>
#include<string.h>
#include<bitset>
#define PI acos(-1.0)
using namespace std;
int main()
{
bitset<4000005> bs(1);
int n,x,sum=0;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&x);
bs|=bs<<x;
sum+=x;
}
if(n==1)
{
printf("%d\n",sum);
return 0;
}
for(int i=(double)sum/2.0+0.5;i<=sum;i++)
{
if(bs[i]==1)
{
printf("%d\n",i);
break;
}
}
return 0;
}