D “云 计 算”

技术产业革命的春风也吹到了广西大学,我们的创新创业项目渐渐有了拥抱云计算的意识,各大ECS厂商1元/月的学生机被团队们广泛采购并商业化使用,这就是一个很好的栗子。

我们都知道,云计算是将计算运行在别的地方,正如我们接下来的问题需要将困难的问题转移到让聪明的你来解决一样。

现在有nnn个三元组(a,b,c)(a,b,c)(a,b,c),你需要将他们以任意顺序安排在一个一维数组里,假设数组下标以111开始,对于一个你安排好之后的数列,我们定义他的价值是:

\sum_{i=1}^{n} [a_i(i + 1) + b_i(n - i) + c_i(i + 2)]

请问这个数列所有可能中,他最小价值应该是多少?

思路:

首先对上述式子进行变形,可以得到

\sum_{i=1}^{n}i(a_i - b_i + c_i) + (a_i + nb_i + 2c_i)

 既然是求和,而对于每一组的 a_i, b_i, c_i 都有 (a_i - nb_i + 2c_i) 不变,且它存在于求和公式中,也就是说这个值不会变并且不影响最终结果

而对于 i(a_i - b_i + c_i) ,显然有 (a_i - b_i + c_i) 不变,也就是说这个结果与系数有关,根据贪心,只需要将以从大到小的顺序进行计算即可

最终计算过程就是对 (a_i - b_i + c_i) 排序后计算

数据很大,注意用long long

#include <bits/stdc++.h>
using namespace std;
int n;
class p {
	private:
		int a, b, c, A, B;
	public:
	p() {

	}
	p(int a, int b, int c) {
		this->a = a;
		this->b = b;
		this->c = c;
		A = (a - b + c);
		B = a + n * b + 2 * c;
	}
	int getA() {
		return A;
	}
	int getB() {
		return B;
	}
};
bool cmp(p a, p b) {
	return a.getA() > b.getA();
}
p arr[100100];
int main()
{
	ios::sync_with_stdio(false);
	cin >> n;
	int sum = 0;
	for (int i = 1; i <= n; i++) {
		int a, b, c;
		cin >> a >> b >> c;
		arr[i] = p(a, b, c);
		sum += arr[i].getB();
	}
	sort(arr + 1, arr + 1 + n, cmp);
	for (int i = 1; i <= n; i++) {
		sum += arr[i].getA() * i;
	}
	cout << sum << "\n";
	return 0;
}
发布了143 篇原创文章 · 获赞 11 · 访问量 8206

猜你喜欢

转载自blog.csdn.net/weixin_43701790/article/details/103500544
今日推荐