L 转: The Heaviest Non-decreasing Subsequence Problem
思路:
考虑到N只有20,可以二进制枚举.即将每一个集合最多N个元素的集合情况枚举出来,并将其第hash一下,(即 对应数的对应位置二进制置为1),记录为该值的hash的个数,然后枚举所有可能情况,统计大于aM的个数即可
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<sstream>
#include<cmath>
using namespace std;
const int maxn = (1<<20)+5;
int n, m, k, now;
int a[55][25];
int geshu[55];
int cnt[maxn];
double ai;
char str[maxn];
void dfs(int cur, int val, int e)
{
if(cur >= e)
{
if(val)
cnt[val]++;
return ;
}
dfs(cur+1, val+(1<<(a[now][cur]-1)), e);
dfs(cur+1, val, e);
}
int main(void)
{
scanf("%d%lf", &n, &ai);
getchar();
m = 1;
while(gets(str) != NULL)
{
// cout << "*" << str << endl;
int len = strlen(str);
int cur = 0, num = 0;
for(int i = 0; i < len; i++)
{
if(str[i] == ' ')
{
a[m][num] = cur;
cur = 0;
num++;
}
else if(i == len-1)
{
cur = cur*10+str[i]-'0';
a[m][num] = cur;
cur = 0;
num++;
}
else
cur = cur*10+str[i]-'0';
}
geshu[m] = num;
m++;
}
m--;
k = ceil(1.0*m*ai);
// cout << k << endl;
for(int i = 1; i <= m; i++)
{
now = i;
dfs(0, 0, geshu[i]);
}
int ans = 0;
// cout << maxn << endl;
for(int i = 1; i < maxn; i++)
if(cnt[i] >= k)
ans++;
printf("%d\n", ans);
// for(int i = 1; i <= n; i++)
// {
// for(int j = 0; j < geshu[i]; j++)
// cout << a[i][j] << ' ';
// cout << endl;
// }
return 0;
}