您的位置:首页 > 产品设计 > UI/UE

UESTC-1633 去年春恨却来时,落花人独立,微雨燕双飞(取模最短路)

2017-08-05 12:05 405 查看
给你一个大小为n的集合S,集合里有n个互不相同正整数.
有q个询问,每次询问是否能选择S中的一些数字 ( 同一个数字可以选择多次,也可以任何数字都不选),使它们相加的和为m.

Input

第一行一个数n(1≤n≤2000),表示集合S的大小.
第二行n个数,第i个数ai(1≤ai≤50000)表示集合S中的第i个数.
第三行一个数q(1≤q≤10000),表示询问次数.
接下来q行,每行一个数m(0≤m≤1000000000),表示该次询问的数.

Output

每次询问输出一行,如果存在和为m的方法,输出YES,否则输出NO.

Sample Input
3
2 4 9
4
6
7
18
25


Sample Output
YES
NO
YES
YES


分析:一样的套路,取a1作为模数,然后跑最短路,对于询问中的一个数x,如果d[x
% a[1]] > x则无解.

#include
<bits/stdc++.h>

#define N 50005

#define MOD 1000000007

using namespace std;

typedef long long ll;

typedef pair<ll,ll> pii;

ll n,x,Q,d
,a
;

bool done
;

priority_queue< pii,vector<pii>,greater<pii> > q;

int main()

{

    cin.sync_with_stdio(false);

    cin>>n;

    for(int i = 1;i <= n;i++) cin>>a[i];

    sort(a+1,a+1+n);

    memset(d,0x3f,sizeof(d));

    memset(done,0,sizeof(done));

    d[0] = 0;

    q.push(make_pair(d[0],0));

    while(!q.empty())

    {

        int u = q.top().second;

        q.pop();

        if(done[u]) continue;

        done[u] = true;

        for(int i = 1;i <= n;i++)

         if(d[(a[i]+u) % a[1]] > d[u] + a[i])

         {

             d[(a[i]+u) % a[1]] = d[u] + a[i];

             q.push(make_pair(d[(a[i]+u) % a[1]],(a[i]+u) % a[1]));

         }

    }

    cin>>Q;

    for(int i = 1;i <= Q;i++)

    {

        cin>>x;

        if(d[x % a[1]] <= x) cout<<"YES"<<endl;

        else cout<<"NO"<<endl;

    }

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: