贪心专题
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); } }

浙公网安备 33010602011771号