TYVJ 1066 合并果子 解题报告
呼,写死我了,最开始写的DP,没太仔细想,结果!!超时,超得真过瘾啊!呵呵,后来知道该用贪心,就是相当于一个”赫夫曼树“,当然,我没用那算法,也不记得那算法了,用的堆,不过也好久没写了,提交至少5次,最后发现主要的问题是出在一个寻找父节点的那个宏上。手生了,联系了一下堆。
#include <stdio.h> #include <stdlib.h> int heap[10001]; int len, ans; #define left(i) (((i) << 1) + 1) #define right(i) (((i) << 1) + 2) //把parent(i) 写成了 i / 2, 应该是(i - 1) / 2 #define parent(i) ((i - 1) >> 1) void add(int k) { int i = len++; while(i != 0 && heap[parent(i)] > k){ heap[i] = heap[parent(i)]; i = parent(i); } heap[i] = k; } int delete(void) { int k = heap[0]; int i = 0, j; len--; while(left(i) < len){ j = -1; if(heap[left(i)] < heap[len]){ j = left(i); } if(right(i) < len && heap[right(i)] < heap[len] && heap[right(i)] < heap[left(i)]){ j = right(i); } if(j == -1){ break; } heap[i] = heap[j]; i = j; } heap[i] = heap[len]; return k; } int main(int argc, char **argv) { int i, j; int n; scanf("%d", &n); for(i = 0; i < n; i++){ scanf("%d", &j); add(j); } for(i = 1; i <= n - 1; i++){ j = delete(); j += delete(); add(j); ans += j; } printf("%d\n", ans); return 0; }