http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3230 贪心+最大二叉堆,写这题主要是练习一下二叉堆,从没写过,每次找最大的b, #include <iostream> #include <algorithm> #define MAXN 100010 using namespace std ; struct Problem { int a , b ; } ; int b[MAXN] ; Problem P[MAXN] ; bool Cmp (Problem e1 , Problem e2) { return e1.a < e2.a ; } void Down (int i , int n) { int s , j ; for (s = b[i] , j = i << 1 ; j <= n ; i = j , j <<= 1) { if (j < n && b[j + 1] > b[j]) j ++ ; if (b[j] > s) b[i] = b[j] ; else break ; } b[i] = s ; } void Insert (int k , int &n) { int i , j ; b[++ n] = k ; for (j = n , i = j >> 1 ; i > 0 ; j = i , i >>= 1) if (b[i] < k) b[j] = b[i] ; else break ; b[j] = k ; } int main () { int n , i , j , m , skill , k ; while (scanf ("%d%d%d" , &n , &m , &skill) != EOF) { for (i = 1 ; i <= n ; i ++) scanf ("%d%d" , &P[i].a , &P[i].b) ; sort (P + 1 , P + n + 1 , Cmp) ; for (j = 1 ; j <= n && P[j].a <= skill ; j ++) b[j] = P[j].b ; k = j - 1 ; for (i = k / 2 ; i > 0 ; i --) Down (i , k) ; while (k && m --) { skill += b[1] ; b[1] = b[k --] ; Down (1 , k) ; for (; j <= n && P[j].a <= skill ; j ++) Insert (P[j].b , k) ; } printf ("%d/n" , skill) ; } return 0 ; }