【题解】Gym100753M
一:【题意】
给定 \(a_{1...n}\), \(q\) 次查询,每次查询一个 \(x\) 是否能用 \(a\) 里面的数线性组合出来(系数 \(>=0\) )
\(n<=5000,q<=10000,x<=1e9,a[i]<=50000\)
二:【解法】
钦定 \(Mod=a[1]\) ,做模 \(Mod\) 意义下的同余 \(BFS\)
\(dis[v]\) 表示 \(\%m==v\) 的数集中 最小可以被线性表示的数
然后判断答案
三:【代码】
#include<bits/stdc++.h>
#define inf 2e9
#define Pair pair<int,int>
#define w first
#define v second
using namespace std;
const int N=5010,M=5e4+10;
int a[N],dis[M],vis[M];
int main(){
for(int i=0;i<M;i++) dis[i]=inf;
int n;cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
sort(a+1,a+1+n);
int up=a[1];
priority_queue<Pair,vector<Pair>,greater<Pair> > q;
q.push({0,0});dis[0]=0;
while(q.size()){
int u=q.top().v;q.pop();
if(vis[u]) continue;
vis[u]=1;
for(int i=2;i<=n;i++){
int v=(u+a[i])%up;
if(dis[v]>dis[u]+a[i]){
dis[v]=dis[u]+a[i];
q.push({dis[v],v});
}
}
}
int qq;cin>>qq;
while(qq--){
int x;cin>>x;
//cout<<"-->";
if(x>=dis[x%up]) cout<<"TAK\n";
else cout<<"NIE\n";
}
return 0;
}

浙公网安备 33010602011771号