HDU
2013-04-14 17:57
302 查看
///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; } /* */
相关文章推荐
- HDU 2093-考试排名(模拟题)
- HDU 1240 Asteroids!
- HDU 3535
- HDU 4293 Groups [DP]
- hdu (1878) 欧拉回路 (the usage of Disjoint set)
- hdu 4545(LCS)
- HDU 4276 The Ghost Blows Light(树形DP)
- hdu——1023(Catalan数)
- hdu 1108 最小公倍数
- HDU 3622 Bomb Game / 2-SAT
- hdu 1050解题报告
- HDU 4864 Task(贪心)
- hdu 4933 孙子定理+数位dp
- hdu-1704 Rank
- HDU—— 1860 统计字符
- hdu 3480 Division(dp四边形优化)
- hdu 1232 畅通工程
- Hdu 5236 Article(dp)
- A - Fire Net - hdu 1045(二分图匹配)
- HDU 3861--The King’s Problem【scc缩点构图 && 二分匹配求最小路径覆盖】