策略
1. 序列问题
题意: 给定一个序列,若y = x * P, 则称这两个元素是互斥的,求一个任意两元素皆不互斥的最长序列元素个数。
算法: 对每一个数,可选择要与不要, 然后衡量要与不要的代价,然后做出选择。
代码:
View Code
#include <stdlib.h> #include <string.h> #include <algorithm> #include <map> using namespace std; int a[100100]; int N,P; long long maxn; map<int,int>mp; map<int,int>HASH; int getval(int x) //取X { int ans = mp[x], num = 1; long long mul = x * P; while( mul <= maxn ) { if( mp.find(mul) == mp.end() ) //如果没有找到这个数 return ans; if( num & 1 ) //如果不要 ans -= mp[mul], ++num; else ans += mp[mul], ++num; mul *= P; if( P == 1 ) break; } return ans; } int getmodi(int x) //取X { int ans = mp[x], num = 1; long long mul = x * P; while( mul <= maxn ) { if( mp.find(mul) == mp.end() ) //如果没有找到这个数 return ans; if( num & 1 ) //如果不要 HASH[mul] = 1,++num; else ans += mp[mul], ++num, HASH[mul] = 1; mul *= P; if( P == 1 ) break; } return ans; } int ungetmodi(int x) //不取X { int ans = 0, num = 1; long long mul = x * P; while( mul <= maxn ) { if( mp.find(mul) == mp.end() ) //如果没有找到这个数 return ans; if( num & 1 ) //如果不要 ans += mp[mul], ++num, HASH[mul] = 1; else HASH[mul] = 1,++num; mul *= P; if( P == 1 ) break; } return ans; } int ungetval(int x) //不取X { int ans = 0, num = 1; long long mul = x * P; while( mul <= maxn ) { if( mp.find(mul) == mp.end() ) return ans; if( num & 1 ) ans += mp[mul], ++num; else ans -= mp[num], ++num; mul *= P; if( P == 1 ) break; } return ans; } int main( ) { while( scanf("%d%d",&N,&P) != EOF) { mp.clear(); HASH.clear(); maxn = 0; for(int i = 0; i < N; ++i) { scanf("%d",&a[i]); ++mp[a[i]]; //printf("%d\n",mp[a[i]]); if( a[i] >= maxn ) maxn = a[i]; } map<int,int>::iterator it = mp.begin(); int ans = 0; for( ; it != mp.end(); ++it) { if( HASH[it->first] != 1 ) { int c1 = getval(it->first); int c2 = ungetval(it->first); //printf("val = %d %d %d\n",it->first, c1,c2); if( c1 >= c2 ) //当前数加入互斥集合 { ans += getmodi(it->first); } else { ans += ungetmodi(it->first); } } } printf("%d\n",ans); } return 0; }

浙公网安备 33010602011771号