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

posted @ 2011-07-06 09:35  zqynux  阅读(530)  评论(0编辑  收藏  举报