贪心算法(01/26)

贪心算法

贪心算法是一个比较容易理解的方法。即把一整个问题分成多个步骤,在每个步骤中都选取当前步骤的最优方案,直到所有的步骤结束,也就是“走一步看一步”
在高中学的时候就差不多是一个盗贼去偷东西,每个东西都有固定的价值和大小,而盗贼只有一个已知大小的包,问怎样才能使偷走的价值最高。这类题很明显的就是对它所含有的价值,也就是对它们的平均价值进行排序,选取单位价值最高的装入包中。这就是所谓贪心。
看一下这一道题

Due to the development of online shopping, the logistics industry which is highly connected with goods shipping has been so prosperous that the great amount of employees is needed.Therefore, Alex, a truck driver in this growing industry, was supposed to transport several parcels scattering in the warehouse to other cities in his daily routine.
According to the official safety requirements to the trucks running in the highway, Alex had to tie up all the packages tightly so that he could settle the goods safely on his truck. Alex knew that the length of the cords needed for bundling the packages on the truck was based on the size of the packages themselves. Also,
n packages can be tied up well after n−1 bundles.Moreover, when bundling goods, Alex could only bundle two packages at one time to avoid scattering. Since the daily consumption of the cord was great and Alex was supposed to pay for it, he hopes to bundle all the goods with the shortest cord.
For example, there are 4 parcels in the size of 8, 5, 14, and 26 respectively. If Alex binds the first two together, the needed rope will be in the length of 13 (8+5 = 13) while the needed rope for the latter two packages will be 40 (14 + 26 = 40). If Alex keeps bundling these two items,the rope length he needs will be 53 (13 + 40 = 53). So the total length of the 4 packages will be 106 (13 + 40 + 53 = 106). If Alex tries another way by bundling the first two (8 + 5 = 13),adding up the third one (13 + 14 = 27), and then bundling the last item (27 + 14 = 53), he will only need the cord in the length of 93 (13 + 27 + 53 = 93). Now your mission is to help Alex finding the minimum length of the needed cord.

Input Format

The first line contains an integer T
indicating the number of test cases. Each test case contains two lines. The first one contains a positive integer n indicating the number of packages. The second one contains n positive integers separated by a space to indicate the size of each parcel.

Output Format

The first line contains an integer T indicating the number of test cases. Each test case contains two lines. The first one contains a positive integer n indicating the number of packages. The second one contains n positive integers separated by a space to indicate the size of each parcel.
Technical Specification
1≤T≤10
1≤n≤1000
The size of each parcel is at most 1000

Sample Input

4
6
2 3 4 4 5 7
5
5 15 40 30 10
10
3 1 5 4 8 2 6 1 1 2
9
3 2 1 6 5 2 6 4 3

Sample Output

63
205
100
98

按照题意,不难理解,也就是先排序好,把最小的两个捆绑好在放入队列进行排序,直到队列只剩下一个,为了防止多次排序,这里就直接用优先排列来做。

#include<bits/stdc++.h>
using namespace std;
int t,n,a,b,c,d;
#define ll long long
ll e;
priority_queue <int,vector<int>,greater<int> > p;
int main(){
	cin>>t;
	while(t--){
		e=0;
		cin>>n;
		while(n--){
			cin>>b;
			p.push(b);
		}
		while(p.size()>1){
			c=p.top();
			p.pop();
			d=p.top();//去除两个头相加
			p.pop();
			b=c+d;
//			cout<<c<<" "<<d<<endl;
			p.push(b);//重新放入队列进行排序
			e+=b;//每次加
		}
		cout<<e<<endl;
		p.pop();
	}
	return 0;
}

再说一说这道题

One day, v11 encounters a group of monsters in a foreast. In order to defend the homeland, V11 picks up his weapon and fights!
All the monsters attack v11 at the same time. Every enemy has its HP, and attack value ATK. In this problem, v11 has his ATK and infinite HP. The damage (also means reduction for HP) is exactly the ATK the attacker has. For example, if v11’s ATK is 13 and the monster’s HP is 27, then after v11’s attack, the monster’s HP become 27 - 13 = 14 and vice versa.
v11 and the monsters attack each other at the same time and they could only attack one time per second. When the monster’s HP is less or equal to 0 , we think this monster was killed, and obviously it would not attack any more. For example, v11’s ATK is 10 and a monster’s HP is 5, v11 attacks and then the monster is killed! However, a monster whose HP is 15 will be killed after v11 attack for two times. v11 will never stop until all the monsters are killed ! He wants to minimum the HP reduction for the fight! Please note that if in some second, some monster will soon be killed , the monster’s attack will works too.

Input

The first line is one integer T indicates the number of the test cases. (T <=100)
Then for each case, The first line have two integers n (0<n<=10000), m (0<m<=100), indicates the number of the monsters and v11’s ATK . The next n lines, each line has two integers hp (0<hp<=20), g(0<g<=1000) ,indicates the monster’s HP and ATK.

Output

Output one line.
First output “Case #idx: ”, here idx is the case number count from 1. Then output the minimum HP reduction for v11 if he arrange his attack order optimal .

Sample Input

2
3 1
1 10
1 20
1 40
1 10
7 3

Sample Output

Case #1: 110
Case #2: 3

这道题由于每次进行攻击后,是受到所有未死的怪物的攻击,而不是单一怪物的攻击。为此,为了尽可能少的受到伤害,我们可以先按怪物伤害和血量的比进行排序,在逐一加上,计算受到最少的伤害。

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;  
struct f{
    long long hp;
    long long atk;
    long long aa;//攻击次数 
}a[11000];
bool cmp(f p,f q){
 return p.atk*q.aa>q.atk*p.aa;
}
int main(){
	int n,atk,m;
	long long sum,ans;
	cin>>n;
	for(int j=1;j<=n;j++){
		sum=0,ans=0;
		cin>>m>>atk;
		for(int i=0; i<m; i++){
			cin>>a[i].hp>>a[i].atk;
			a[i].aa=a[i].hp/atk+(a[i].hp%atk?1:0);
		}
		sort(a,a+m,cmp);
		for(int i=0; i<m; i++){
			ans+=a[i].aa;
//			cout<<a[i].atk<<endl;
			sum+=(ans*a[i].atk);
		} 
		cout <<"Case #"<<j<<": "<<sum<< endl;
	} 
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值