Problem H
2013-04-01 11:57
274 查看
题意: 从数组中选出最大的集合, 使任意两两不能满足a * k = b or b * k = a;(数组元素唯一)
分析1(TLE): 二分图 最大匹配
分析2(AC): 贪心的思想, 先排个小到大的序, 对于整个集合, 如果a[i]和a[j](a[j] == a[i] * k, i肯定小于j),
那么有三种选择使得这个集合满足条件: 1. 舍弃a[i],a[j]; 2.舍弃a[i]; 3.舍弃a[j];
如果选择2, 我们无法知道是否存在a[j] * k, 如果存在, 有得舍弃其中一个
如果选择1. 那就必然不能得到最大
显然, 选择3是必须的, 同时也满足最优的情形, a[i]留着不会影响后面的数, a[j]留着会冲突, 不留a[i]可能少, 所以不留a[j]是局部最优的, 也是全局最优
对于每个留在集合里的数, 二分找出是否存在k倍的数, 存在则舍去,留着的就是最大值, 复杂度为O(n* Log(n)) + O(log(n))
算法: 二分答案(这个二分结合了分治)
分析1(TLE): 二分图 最大匹配
分析2(AC): 贪心的思想, 先排个小到大的序, 对于整个集合, 如果a[i]和a[j](a[j] == a[i] * k, i肯定小于j),
那么有三种选择使得这个集合满足条件: 1. 舍弃a[i],a[j]; 2.舍弃a[i]; 3.舍弃a[j];
如果选择2, 我们无法知道是否存在a[j] * k, 如果存在, 有得舍弃其中一个
如果选择1. 那就必然不能得到最大
显然, 选择3是必须的, 同时也满足最优的情形, a[i]留着不会影响后面的数, a[j]留着会冲突, 不留a[i]可能少, 所以不留a[j]是局部最优的, 也是全局最优
对于每个留在集合里的数, 二分找出是否存在k倍的数, 存在则舍去,留着的就是最大值, 复杂度为O(n* Log(n)) + O(log(n))
算法: 二分答案(这个二分结合了分治)
#include <iostream> #include <cstdio> #include <queue> #include <cstring> #include <cmath> #include <vector> #include <set> #include <stack> #include <algorithm> //#include "myAlgorithm.h" #define MAX 100005 #define INF 1e18 #define eps 1e-5 using namespace std; long long upVal = INF + 5; int n; long long k; long long a[MAX]; bool find( const long long val, int d, int u) { int D = d, U = u;///mid才最后答案 while(D < U - 1) ///中间有数才继续寻找 { int mid = (D + U)>>1; if(a[mid] == upVal){ int dd = mid, du = mid; bool res1 = false, res2 = false; while(D < dd && a[dd] == upVal)dd--; if(D != dd){ res1 = find(val, D, dd + 1); } while(U > du && a[du] == upVal)du++; if(U != du){ res2 = find(val, du - 1, U); } return (res1 || res2); } if(a[mid] == val) { a[mid] = upVal; //cout<<"return "<<mid<<endl; return true; } else if(a[mid] < val) { D = mid; } else { U = mid; } } return false; } int main() { //freopen("in.txt", "w", stdout); while(cin>>n>>k) { for(int i = 1; i <= n; i++) { cin>>a[i]; } sort(a + 1, a + n + 1); int ans = n; for(int i = 1; i <= n; i++) { if(a[i] != upVal) { long long val = a[i] * k; if(find(val, i, n + 1)) { ans--; } } } cout<<ans<<endl; } return 0; }
相关文章推荐
- CCNU 2012.7.8 Problem H
- 图算法—Problem H
- Problem H 一道水题
- Problem H
- Problem H: 悦动达人
- 2016SDAU课程练习四1008 Problem H
- 【线段树】【4-6组队赛】Problem H
- 《ACM程序设计》书中题目--problem h
- 【线段树】【4-6组队赛】Problem H
- Problem H: STL——字符串排序
- 【NYIST】暑假训练赛 (一)-----Problem H
- ACM递归递推练习 Problem H
- Problem H
- Problem H: 正方形、长方形、立方体
- Problem H
- Problem H
- Problem H
- SCUT Training 20170913 Problem H
- Problem H: 今年第几天?
- SCUT Training 20170920 Problem H