【题解】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;
}
posted @ 2026-01-13 08:39  Ming3398  阅读(16)  评论(0)    收藏  举报