Frequent Subsets Problem

The frequent subset problem is defined as follows. Suppose UU={1, 2,\ldots…,N} is the universe, and S_{1}S1S_{2}S2,\ldots…,S_{M}SMare MM sets over UU. Given a positive constant \alphaα, 0<\alpha \leq 10<α1, a subset BB (B \neq 0B0) is α-frequent if it is contained in at least \alpha MαM sets of S_{1}S1S_{2}S2,\ldots…,S_{M}SM, i.e. \left | \left \{ i:B\subseteq S_{i} \right \} \right | \geq \alpha M{i:BSi}αM. The frequent subset problem is to find all the subsets that are α-frequent. For example, let U=\{1, 2,3,4,5\}U={1,2,3,4,5}, M=3M=3, \alpha =0.5α=0.5, and S_{1}=\{1, 5\}S1={1,5}, S_{2}=\{1,2,5\}S2={1,2,5}, S_{3}=\{1,3,4\}S3={1,3,4}. Then there are 33 α-frequent subsets of UU, which are \{1\}{1},\{5\}{5} and \{1,5\}{1,5}.

Input Format

The first line contains two numbers NN and \alphaα, where NN is a positive integers, and \alphaα is a floating-point number between 0 and 1. Each of the subsequent lines contains a set which consists of a sequence of positive integers separated by blanks, i.e., line i + 1i+1 contains S_{i}Si1 \le i \le M1iM . Your program should be able to handle NN up to 2020 and MM up to 5050.

Output Format

The number of \alphaα-frequent subsets.

样例输入

15 0.4
1 8 14 4 13 2
3 7 11 6
10 8 4 2
9 3 12 7 15 2
8 3 2 4 5

样例输出

11

这几天天天写dp,但是基本上是碰见一天写一题先是状态压缩的dp,写了两道有换成了区间dp的题,后来又换成了概率的和数位dp,现在写一些简单的状态压缩dp已经没有什么问题了,决定现在先学会数位dp然后开始努力刷dp题(当然是各种dp),希望能在一个整体上提高。。
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
#include <math.h>
#include <string.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 20
#define mid 1e-8
#define LL long long
/********************************************************/
int Map[55];
int main()
{
    int T, t=1, m, n, x;
    double a;
    char ch;

    scanf("%d%lf", &n, &a);
    memset(Map, 0, sizeof(Map));

    m=0;
    while(scanf("%d", &x)!=EOF)
    {
        ch=getchar();
        Map[m]=Map[m]|(1<<(x-1));
        if(ch=='\n') m++;
    }

    a=ceil(a*m);
    x=0;
    for(int i=1;i<(1<<n);i++)
    {
        int sum=0;
        for(int j=0;j<m;j++)
        {
            if((Map[j]&i)==i)
            {
                sum++;
            }
        }
        if(sum>=a) x++;
    }

    printf("%d\n", x);
    return 0;
}

 

posted on 2018-01-29 22:11  小春天  阅读(110)  评论(0编辑  收藏  举报

导航