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

cf--E. The Values You Can Make(dp)

2016-09-21 19:51 411 查看
Today Pari and Arya are playing a game called Remainders.

Pari chooses two positive integer x and k, and tells Arya k but
not x. Arya have to find the value 

.
There are n ancient numbersc1, c2, ..., cn and
Pari has to tell Arya 

 if Arya wants. Given k and
the ancient values, tell us if Arya has a winning strategy independent of value of x or not. Formally, is it true that Arya can understand the value 

 for
any positive integer x?

Note, that 

 means the remainder of x after
dividing it by y.

Input

The first line of the input contains two integers n and k (1 ≤ n,  k ≤ 1 000 000) —
the number of ancient integers and value k that is chosen by Pari.

The second line contains n integers c1, c2, ..., cn (1 ≤ ci ≤ 1 000 000).

Output

Print "Yes" (without quotes) if Arya has a winning strategy independent of value of x, or "No" (without quotes)
otherwise.

Sample Input

Input
4 5
2 3 5 12


Output
Yes


Input
2 7
2 3


Output
No


Hint

In the first sample, Arya can understand 

 because 5 is
one of the ancient numbers.

In the second sample, Arya can't be sure what 

 is. For example 1 and 7 have
the same remainders after dividing by 2 and 3, but they differ in remainders after dividing by 7.

思路:刚看这个题就知道是一道dp的题,但研究很长时间苦于找出dp的状态方程,后来在瞻仰了大神的博客才勉强明白一丢丢;

dp[i][j][p]表示到第i个数,当前所有数之和为j的 一个子集能否组成p,如果等于1能组成,=0不能组成

到第 i个数(a)时能组成p有三种可能:

1,不使用第i个数:dp[i-1][j][p]=1;

2,使用第i个数,但不属于子集中:dp[i-1][j-a][p]=1;

3.使用第i个数,也属于子集:dp[i-1][j-a][p-a]=1;

ac代码:

#include <iostream>

#include <stdio.h>

#include <cstring>

#include <algorithm>

#include <vector>

using namespace std;

bool dp[501][501][501];

vector<int> p;

int main()

{

    int n,k,a;

    while(~scanf("%d%d",&
4000
amp;n,&k))

    {

       memset(dp,0,sizeof(dp));

       dp[0][0][0]=1;

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

       {

           scanf("%d",&a);

           for(int j=0;j<=500;j++)

           {

               for(int p=0;p<=j&&p<=k;p++)

               {

                   if(dp[i-1][j][p]||(j>=a&&dp[i-1][j-a][p])||(p>=a&&dp[i-1][j-a][p-a]))

                   dp[i][j][p]=1;

               }

           }

       }

       for(int i=0;i<=k;i++)

       {

           if(dp
[k][i]==1)

           p.push_back(i);

       }

       int len=p.size();

       cout<<len<<endl;

       for(int i=0;i<len-1;i++)

       cout<<p[i]<<" ";

       cout<<p[len-1]<<endl;

    }

    return 0;

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