poj-2231

22 篇文章 0 订阅
//264K	47MS	C++
#include <cstdio>
#include <cstring>
#include <cstdlib>

const int MAX = 10005;

long long cowLocation[10005];

int cmp(const void * a, const void * b) {
	return *((long long *)a) - *((long long *)b);
}

long long cowNum;

long long sum;

long long curLeftSum;
long long curRightSum;

long long leftCowNum;
long long rightCowNum;

int main() {
	while(scanf("%lld", &cowNum) != EOF) {
		sum = 0;
		curLeftSum = 0;
		curRightSum = 0;
		for (long long i = 0; i < cowNum; i++) {
			scanf("%lld", &cowLocation[i]);
		}
		qsort(cowLocation, cowNum, sizeof(long long), cmp);
		for (long long i = 1; i < cowNum; i++) {
			curRightSum += cowLocation[i] - cowLocation[0];
			// printf("V %lld\n", cowLocation[i]);
		}
		sum += (curRightSum + curLeftSum);

		long long prevCowId = 0;
		long long curCowId = 1;
		leftCowNum = 0;
		rightCowNum = cowNum - 1;
		while(rightCowNum) {
			// printf("%d\n", rightCowNum);
			long long varyDistance = cowLocation[curCowId] - cowLocation[prevCowId];
			curRightSum -= rightCowNum*(varyDistance);
			rightCowNum--;
			leftCowNum++;
			curLeftSum += leftCowNum*(varyDistance);
			sum += (curRightSum + curLeftSum);
			// printf("AA %lld %lld %lld %lld %lld %lld\n",
			 	// sum, curRightSum, curLeftSum,
			 	// rightCowNum, leftCowNum, varyDistance);
			curCowId++;
			prevCowId++;		
		}
		printf("%lld\n", sum);
	}
}


虽然分类是排序,但是排序在这里只是一个预处理的角色,真正的思路是递推,和编程之美上的坐电梯那道题有点像,其实就是DP啦。

如果知道在某个位置的cow K, 其左边cow的数量是leftCowNum, 右边cow数量是 rightCowNum, 其他cow的位置也都知道,就可以求出,

K与其他cow的距离的和,两部分: 与左边cow的距离的和 leftCowSum, 和 右边cow的距离的和rightCowSum, 两者相加就是K带来的volume,

而要求 K后面一位的cow K+1, 只需在原来的leftCowNum和 rightCowNum进行 加减一定量的大小(细节在code里面,也很简单)既可以 递推出来,就这样遍历一遍cow,将每个cow的volume相加,就是最后的结果.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值