策略

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;    
}

 

posted on 2013-03-26 15:38  luckyboy1991  阅读(152)  评论(0编辑  收藏  举报