C++ 贪心算法解题报告

这道题是贪心算法的例题–奶牛的声音
Farmer John has received a noise complaint from his neighbor, Farmer Bob, stating that his cows are making too much noise.

FJ’s N cows (1 <= N <= 10,000) all graze at various locations on a long one-dimensional pasture. The cows are very chatty animals. Every pair of cows simultaneously carries on a conversation (so every cow is simultaneously MOOing at all of the N-1 other cows). When cow i MOOs at cow j, the volume of this MOO must be equal to the distance between i and j, in order for j to be able to hear the MOO at all. Please help FJ compute the total volume of sound being generated by all N*(N-1) simultaneous MOOing sessions.

Input

  • Line 1: N
  • Lines 2…N+1: The location of each cow (in the range 0…1,000,000,000).

Output
There are five cows at locations 1, 5, 3, 2, and 4.

Sample Input
5
1
5
3
2
4

Sample Output
40

Hint
INPUT DETAILS:
There are five cows at locations 1, 5, 3, 2, and 4.

OUTPUT DETAILS:
Cow at 1 contributes 1+2+3+4=10, cow at 5 contributes 4+3+2+1=10, cow at 3 contributes 2+1+1+2=6, cow at 2 contributes 1+1+2+3=7, and cow at 4 contributes 3+2+1+1=7. The total volume is (10+10+6+7+7) = 40.

题目描述
农夫约翰最近忘记他有多少奶牛了!于是他决定用一个特别新颖的方法来计算奶牛的数量。他在每块农田上都安装一个麦克风,通过麦克风的音量来计算每个农田上有多少奶牛。
约翰的N个农田是排成一条直线,每个农田上可能拥有不同种类的奶牛,奶牛的种类是B种,第i种奶牛每只奶牛都会发出Vi的音量。然后,由于农场里是经常有风的,风的方向是从左到右的,风使得奶牛的声音也从左到右吹了过去。如果声音在某块农田的音量是X,那么接下来风将把X-1音量的声音带到下一个(右边)那个农田上去。因此每块农田上的音量等于本身这块农田上奶牛发出的声音加上左边相邻的农田音量X-1。
给定从左到右每块农田上的音量,请帮助约翰计算他最少有多少数量的奶牛。
输入
第一行两个正整数N和B。
第2行到第B+1行,第i+1行的整数表示Vi。
第B+2行到第B+i+1行,表示从左到右每块农田上的监测到的音量。
输出
输出最少可能有多少奶牛,如果不能确定的话,就输出-1。

翻译是英文版的翻译,但是可能对于题目来说帮助不是特别大,本题的解题思路主要利用贪心算法的思想,如果使用双重循环最终结果乘2的算法,是会超时的,但是如果利用一些算法,本题会简单许多,也不会超时。

下面先看一下代码:

#include <iostream>
#include<algorithm>
#include <cstring>
#include <iomanip>
using namespace std;
int n;
long long  a[10005];
long long sum;
long long dp[10005];
int main()
{
	while (cin >> n)
	{
		for (int i = 1; i <= n; i++)
			cin >> a[i];
		sort(a + 1, a + n + 1);
		dp[1] = 0;
		for (int i = 2; i <= n; i++)
		{
			dp[i] = dp[i - 1] + (a[i] - a[i - 1])*(i - 1);
			sum += dp[i];
		}
		dp[n] = 0;
		for (int i = n - 1; i >= 1; i--)
		{
			dp[i] = dp[i + 1] + (a[i + 1] - a[i])*(n - i);
			sum += dp[i];
		}
		cout << sum << endl;
	}
	return 0;
}

代码首先进行输入,以a[]为数组名,对整体数组进行赋值,sort函数是利用贪心算法的第一步,然后进行新的数组循环,计算出从数组头到尾一条线的距离,当然由于本题的叫声是双向的,也同样要从数组的末尾向开头进行计算距离,进行两个一重循环,通过sum进行累加,得出结果。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值