HDU

来源:互联网 发布:蒲城网络党校 编辑:程序博客网 时间:2024/06/11 03:33
///tooYang了, 直接每次枚举题目就重复计算很多次了,  预处理一下题目的枚举, 就可以A了#include <iostream>#include <cstdio>#include <queue>#include <cstring>#include <cmath>#include <vector>#include <set>#include <stack>#include <algorithm>//#include "myAlgorithm.h"#define MAX 10005#define OFFENCE (1e9 + 5)#define INF (1e8 + 5)#define eps 1e-9#define Rep(s, e) for( int i = s; i <= e; i++)#define Cep(e, s) for( int i = e; i >= s; i --)#define PI acos(-1.0)//#pragma comment(linker, "/STACK:36777216") ///传说中的外挂using namespace std;int N, M , K;int p[MAX];vector<int>pro[20];int stu[MAX];bool getStu(int allCan){    int ans = 0;    Rep(0, N - 1){        if((stu[i] & allCan) == allCan){            ans ++;        }    }    return ans >= K;}bool isFind;void check002(int len, int allCan, int count, int pos){    if(isFind)return ;    if(count == len && getStu(allCan)){///搜索树中的1的个数为len的节点需要判断            isFind = true;            return ;    }    if( pos >=M || count > len){        return ;    }///搜索结束    check002(len, allCan | (1<< pos), count + 1, pos + 1);    check002(len, allCan, count, pos + 1);    ///枚举二进制数, 当前两个分支, 要么放1, 要么放0}///------------------------直接搜索TLE掉了--------/** 借鉴了亮神的程序, 预处理对题目的枚举, 减少,重复计算次数, 这样就很快了*////-----------------------------------------再换check- 增加预处理-----------void shown(int val){   for(int i = 0; i < 15; i++){        cout<<(val &1 )<<" ";        val >>= 1;    }cout<<endl;}bool v[MAX];void dfs(int len, int count, int pos, int val){    if(count == len){        pro[len].push_back(val);    }    if(count > len)return ;    v[pos] = 1;    for(int i = pos + 1; i <= 15; i++){        if(!v[i]){            dfs(len, count + 1, i, val | 1<<(i - 1));        }    }    v[pos] = 0;}void makeList( )///预处理题目枚举{    for(int i = 1; i <= 15; i++){        dfs(i, 0, 0, 0);    }}bool check003(int num){    int len = pro[num].size();    Rep(0, len - 1){        int ans = 0;        for(int j = 0; j < N; j++){            if((pro[num][i] & stu[j]) == pro[num][i]){                ans ++;            }        }        if(ans >= K)            return true;    }    return false;}int find(){    int d = 1, u = M, mid;///    int ans = 0;    while(u - d >= 0){///        mid = (d + u)/2;        if(check003(mid)){///选择mid个题,  然后枚举mid, 看是否存在>=K人做出            ans = max(ans, mid);            d = mid + 1;        }else {            u = mid - 1;        }    }    return ans;}int main() {    makeList( );//    cout<<pro[14].size()<<endl;//    Rep(0, pro[14].size() - 1){//        shown(pro[14][i]);//    }    //freopen("in.tx0t", "w", stdout);    while(scanf("%d %d %d", &N, &M, &K) != EOF){        int pp, pt;        Rep(0, N - 1){           scanf("%*s %d", &pp);            stu[i] = 0;            for(int j = 0; j < pp; j++){                scanf("%d", &pt);                stu[i] |= (1<<(pt - 1));            }        }        printf("%d\n", find());    }    return 0;}/**/


 

原创粉丝点击