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 T≤5 , which represents the number of testcases.
For each testcase, there are two lines:
1. The first line contains two integersn and a (1≤n≤20,1≤a≤106 ).
2. The second line containsn integers b1,…,bn (∀1≤i≤n,1≤bi≤106 ).
For each testcase, there are two lines:
1. The first line contains two integers
2. The second line contains
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