HDU Untitled(状压DP OR dfs枚举子集)

来源:互联网 发布:cnki中国期刊数据库 编辑:程序博客网 时间:2024/05/29 16:30

Untitled

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 325    Accepted Submission(s): 169


Problem Description
There is an integer a and n integers b1,,bn. After selecting some numbers from b1,,bn in any order, say c1,,cr, we want to make sure that a mod c1 mod c2 mod mod cr=0 (i.e., a will become the remainder divided by ci each time, and at the end, we want a to become 0). Please determine the minimum value of r. If the goal cannot be achieved, print 1 instead.
 

Input
The first line contains one integer T5, which represents the number of testcases. 

For each testcase, there are two lines:

1. The first line contains two integers n and a (1n20,1a106).

2. The second line contains n integers b1,,bn (1in,1bi106).
 

Output
Print T answers in T lines.
 

Sample Input
22 92 72 96 7
 

Sample Output
2-1
 

Source
BestCoder Round #49 ($)
 

Recommend
hujie
 


大致题意:

20个数,求选出最少的数然后这些数的某种排列可以连续模a得到0


思路:显然先模大的数,再模小的数,否则没意义

所以状压枚举子集,1<<20 = 100w 然后dp,用了lowbit优化了一下

//#pragma comment(linker, "/STACK:1024000000,1024000000")#include <iostream>#include <cstring>#include <cmath>#include <queue>#include <stack>#include <map>#include <set>#include <string>#include <vector>#include <cstdio>#include <ctime>#include <bitset>#include <algorithm>#define SZ(x) ((int)(x).size())#define ALL(v) (v).begin(), (v).end()#define foreach(i, v) for (__typeof((v).begin()) i = (v).begin(); i != (v).end(); ++ i)#define REP(i,n) for ( int i=1; i<=int(n); i++ )using namespace std;typedef long long ll;#define X first#define Y secondtypedef pair<int,int> pii;template <class T>inline bool RD(T &ret) {        char c; int sgn;        if (c = getchar(), c == EOF) return 0;        while (c != '-' && (c<'0' || c>'9')) c = getchar();        sgn = (c == '-') ? -1 : 1;        ret = (c == '-') ? 0 : (c - '0');        while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0');        ret *= sgn;        return 1;}template <class T>inline void PT(T x){        if (x < 0) {                putchar('-');                x = -x;        }        if (x > 9) pt(x / 10);        putchar(x % 10 + '0');}const int N = 22;int m[25];int dp[1<<N];int sum[1<<N];int inline lowbit(int x){        return x & -x;}bool cmp(int a,int b){        return a > b;}int vs[1<<N];int main(){        for(int i = 0; i<=  20;i++) vs[1<<i] = i;        int T;        cin>>T;        while(T--){                memset(sum,0,sizeof(sum));                int n,a;                RD(n),RD(a);                REP(i,n) RD(m[i-1]);                sort(m,m+n);                REP(i,n) {                        dp[1<<(i-1)] = a%m[i-1];                        sum[1<<(i-1)] = 1;                }                int ans = 100;                for(int i = 1;i < (1<<n);i++){                        int cur = i;                        if(sum[cur] == 0){                                sum[cur] = sum[cur-lowbit(cur)] + sum[lowbit(cur)];                                dp[cur] = dp[cur-lowbit(cur)]%m[vs[lowbit(cur)]];                        }                        if( dp[cur] == 0) ans = min(ans,sum[cur]);                }                if(ans == 100) puts("-1");                else printf("%d\n",ans);        }}


0 0
原创粉丝点击