贪心专题

1.客户数量

题目:http://www.acmore.net/problem.php?id=1485

算法: 首先要证明把X分成全部为1,每次折办分最优。

           用队列维护x,不断求X,分段求出前10000的数,否则会TLE

           按到达时间 + 切糕时间排序~~

代码:

View Code
#include <stdio.h>
#include <algorithm>
#include <stdlib.h>
#include <string.h>
#include <queue>
using namespace std;
#define MAXN 100010

struct node
{
  long long t,v,m;
  bool operator < (const node &A) const 
  {
    return m < A.m;
  }
}M[100010];

long long hash[100010];

struct Val
{
 long long v;
 short cnt;
}qq;

queue<Val>q;

long long fun(long long t)
{
  if( t <= 1 ) return 0;
  struct Val  l;
  l.cnt = 1;
  l.v = t;
  q.push(l);
  long long sum = 0;
  while( !q.empty() )
  {
   qq = q.front();
   q.pop();
   long long x = qq.v;
   long long temp = x >> 1;
   if( x  % 2 == 0 )
   {
      sum += (temp)*(temp) * qq.cnt;
      if( temp > 1 )
      {
       if( temp < MAXN && hash[temp] ) { sum += hash[temp] * 2; continue; }
       l.cnt = 2;
       l.v = temp;
       q.push( l );
      }
   }
   else
   {
      sum += temp * ( x - temp) * qq.cnt;
      int flag = 0;
      if(temp  > 1 )
      {
        if( temp < MAXN && hash[temp] ) { sum += hash[temp]; flag = 1; }
        if( !flag )
        {
         l.v = temp;
         l.cnt = 1; 
         q.push(l);
        }
      }
      if( (x - temp) > 1 )
      { 
        if( (x-temp) < MAXN && hash[x-temp] ) { sum += hash[x - temp]; continue; }
        l.v = x - temp;
        l.cnt = 1;
        q.push(l);
      }
    } 

  }
  return sum;
}

int main( )
{
  int N;
  memset(hash,0,sizeof(hash));
  for(int i = 0; i <= 1000; i++)
  {
     hash[i] = fun(i);
  } 
  for(int i = 1001; i <= 10000; i++)
  {
     hash[i] = fun(i);
  } 
  for(int i = 10001; i <= 100000; i++)
  {
     hash[i] = fun(i);
  } 
  while( scanf("%d",&N) != EOF )
  {
     for(int i = 1; i <= N; ++i)
     {
    scanf("%lld%lld",&M[i-1].t,&M[i-1].v);
        M[i-1].m = M[i-1].t + fun(M[i-1].v);
     }
     sort(M,M + N);
     long long temp = 0;
     int cnt = 0;
     long long maxnt = 0;
     for(int i = 0; i < N; ++i)
     {
        if( temp <= M[i].t  && maxnt < M[i].t )
         {
           ++cnt;
           temp = max( M[i].m, temp);
           maxnt = max(maxnt,M[i].t);
         }
       
     }
     printf("%d\n",cnt);
  }

}

 

posted on 2013-04-12 12:10  luckyboy1991  阅读(118)  评论(0编辑  收藏  举报