Gym 101666L Lemonade Trade(高精度+贪心)

Gym 101666L Lemonade Trade

Description

The lunch break just started! Your mother gave you one litre of pink lemonade. You do not like pink lemonade and want blue lemonade instead. Fortunately for you the other children in class are willing to trade with you.
Each of them is willing to offer you any quantity of the virtually infinite amount of lemonade they got from their mother, in exchange for their favourite lemonade, according to some exchange rate. The other children are sitting in a long row in the class room and you will walk along the row, passing each child only once. You are not allowed to walk back! Of course, you want to maximise the amount of blue lemonade you end up with. In case you can obtain more than 10 litres of blue lemonade, this is more than you will need, and you will throw away any excess (and keep the 10 litres).
Fortunately, you know in advance what everybody is offering for trade. Your task is to write a program to find the maximum amount of blue lemonade that you can obtain.

Input

The input consists of the following:
• One line containing a single integer 0 ≤ N ≤ 105, the number of children in the classroom, excluding yourself;
• N lines, each containing two strings O, W and a floating point number 0.5 < R < 2,the name of the lemonade that is offered, the name of the lemonade that is wanted,and the exchange rate: for every litre of lemonade W that you trade you get R litres of lemonade O in return.
All strings are guaranteed to have at most 10 alphanumeric characters.

Output

Output a single line containing a single floating point number M, the maximum amount (in litres) of blue lemonade that you can obtain. In case you could obtain more than 10 litres, M is considered to be 10. You are required to output M with absolute precision 10−6 .

Sample Input 1

3
blue pink 1.0
red pink 1.5
blue red 1.0

Sample Output 1

1.500000000000000

Sample Input 2

2
blue red 1.0
red pink 1.5

Sample Output 2

0.000000000000000

Sample Input 3

4
orange pink 1.9
yellow orange 1.9
green yellow 1.9
blue green 1.9

Sample Output 3

10.000000000000000

Sample Input 4

8
red pink 1.9
orange red 1.9
yellow orange 1.9
green yellow 1.9
indigo green 0.6
violet indigo 0.6
purple violet 0.6
blue purple 0.6

Sample Output 4

1.688960160000000

题解

题意

给出一个序列,表示商人可以按照一定比率交换不同颜色的柠檬水。问最开始给你1公升粉色柠檬水,最多可以交换出多少升的蓝色柠檬水。如果大于10公升,输出10。

思路

map存储当前能够换得的该颜色的柠檬水的最大公升。简单思考可以知道,一次交换一定是全部交换最优。所以只要保存当前状态下,不同颜色能持有的最大公升数即可。

注意:本题给出的N较大,简单的连乘的精度不足,所以需要转换为log,变为相加操作。需要判断是否为0,简单判断==0即可,因为只有没有交换到蓝色的情况下,蓝色一定初始化为0。第11组数据专门卡这种情况。

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-9;
const int INF = 0x3f3f3f3f;
int T;


map<string,long double> m1;
string s1,s2;
long double rate; 

int main() {
    while(~scanf("%d",&T)){
    	m1.clear();
    	m1["pink"] = 0.0;
		while(T--){
			cin>>s1>>s2>>rate;
			long double cur = log10(rate);
			if(!m1.count(s2)) continue;
			if(!m1.count(s1)) m1[s1] = m1[s2]+cur;
			else	m1[s1] = max(m1[s1],m1[s2]+cur);
			
		}
		long double ans = m1["blue"];
		if(ans-1.0> eps) printf("10.0
");
    	else if(ans==0) printf("0.0
");
    	else{
			ans = pow(10,ans);
			printf("%.15Lf
",ans);
		}
	}
}
原文地址:https://www.cnblogs.com/caomingpei/p/9694921.html