【题解】【AcWing】1521. 魔术卷

1521. 魔术卷

原题传送:AcWing 1521. 魔术卷

火星上的魔术商店正在提供一些魔术优惠券。

每个优惠券上都印有一个整数 N N N ,当你将此优惠券用于产品时,商店会给你 N N N 倍于该商品价值的钱。

此外,该商店还免费提供一些赠品。

如果你将印有正整数 N N N 的优惠券用于赠品,你就必须向商店支付 N N N 乘以赠品价值的钱。

但是,神奇的是,他们有一些 N N N 为负数的优惠券!

例如,给定一组优惠券,上面印的数字依次为{1 2 4 -1}以及一组产品,价值分别为{7 6 -2 -3}(产品价值为负的是赠品)。

你可以使用第三张优惠券购买第一个产品,得到 28 28 28 元,使用第二张优惠券购买第二个产品,得到 12 12 12 元,使用第四张优惠券购买第四个产品,得到 3 3 3 元。

也就是说,你通过合理使用优惠券,最多可以从商店那里拿走 43 43 43 元钱。

现在,给定你若干的优惠券和若干的商品,每个优惠券和商品最多只能选择一次,请问你最多可以从商店里拿回多少钱。

输入格式

第一行包含一个整数 N c N_c Nc ,表示优惠卷数量。

第二行包含 N c N_c Nc 个整数,表示各优惠券上印有的数值。

第三行包含一个整数 N p N_p Np ,表示产品数量。

第四行包含 N p N_p Np 个整数,表示各产品的价值。

输出格式

输出一个整数,表示最多可以拿回的钱数。

数据范围

1 ≤ N c , N p ≤ 1 0 5 1 \le N_c,N_p \le 10^5 1Nc,Np105 ,
输入的两个整数序列中的元素的绝对值均不超过 100 100 100

输入样例:
4
1 2 4 -1
4
7 6 -2 -3
输出样例:
43
思路:

正序将负数和负数配对计算乘积,钱数最多;倒序将正数和正数配对计算乘积,钱数最多;正数和负数的乘积为负数,会使总钱数减少,所以负负加正正为最多的钱数。

题解:
#include<bits/stdc++.h>

using namespace std;

int main()
{
	int n, m, sum = 0;
	vector<int> v1, v2, w1, w2;
	
	cin >> n;
	while(n--)
	{
		int x;
		cin >> x;
		if(x > 0)
			v1.push_back(x);
		else if(x < 0)
			v2.push_back(x);
	}
	
	sort(v1.rbegin(), v1.rend());
	sort(v2.begin(), v2.end());
	
	cin >> m;
	while(m--)
	{
		int x;
		cin >> x;
		if(x > 0)
			w1.push_back(x);
		else if(x < 0)
			w2.push_back(x);
	}
	
	sort(w1.rbegin(), w1.rend());
	sort(w2.begin(), w2.end());
	
	for(int i = 0; i < min(v1.size(), w1.size()); i++)
		sum += v1[i] * w1[i];
	for(int i = 0; i < min(v2.size(), w2.size()); i++)
		sum += v2[i] * w2[i];
    	
    cout << sum << endl;
    	
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值