码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-08-02 01:03:07      阅读:103      评论:0      收藏:0      [点我收藏+]

标签:

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
2 2 9 2 7 2 9 6 7
 

Sample Output
2 -1
 

Source
 

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 second
typedef 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);
        }
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

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

标签:

原文地址:http://blog.csdn.net/kalilili/article/details/47193711

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!