当前位置: 首页 > 工具软件 > Gaunt > 使用案例 >

Marvolo Gaunt's Ring(类似于dp的做法)

阎功
2023-12-01

题目:(题目传送门

Professor Dumbledore is helping Harry destroy the Horcruxes. He went to Gaunt Shack as he suspected a Horcrux to be present there. He saw Marvolo Gaunt’s Ring and identified it as a Horcrux. Although he destroyed it, he is still affected by its curse. Professor Snape is helping Dumbledore remove the curse. For this, he wants to give Dumbledore exactly x drops of the potion he made.

Value of x is calculated as maximum of p·ai + q·aj + r·ak for given p, q, r and array a1, a2, … an such that 1 ≤ i ≤ j ≤ k ≤ n. Help Snape find the value of x. Do note that the value of x may be negative.

Input
First line of input contains 4 integers n, p, q, r ( - 109 ≤ p, q, r ≤ 109, 1 ≤ n ≤ 105).

Next line of input contains n space separated integers a1, a2, … an ( - 109 ≤ ai ≤ 109).

Output
Output a single integer the maximum value of p·ai + q·aj + r·ak that can be obtained provided 1 ≤ i ≤ j ≤ k ≤ n.

Examples
Input
5 1 2 3
1 2 3 4 5
Output
30
Input
5 1 2 -3
-1 -2 -3 -4 -5
Output
12
Note
In the first sample case, we can take i = j = k = 5, thus making the answer as 1·5 + 2·5 + 3·5 = 30.

In second sample case, selecting i = j = 1 and k = 5 gives the answer 12.

题意

给你三个数p,q,r,给你一个数组,a1,a2,a3,a4 ai,aj,ak,…让你求pai+qaj+r*ak的最大值,并且有个要求,那就是
1 ≤ i ≤ j ≤ k ≤ n. ,也就是说不能在数组中随便找三个数进行相乘
我们要找最优的方案,类似于动态规划

#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include<stdio.h>
#include<string.h>
#include<limits.h>
#include<vector>
#include<queue>
#include<map>
#define ll long long 
using namespace std;
const int maxn=100023;
ll a[maxn];//存的是题目中所给数组
ll n;
ll pp;//
ll qq;
ll rr;
int main()
{
	int i,j;
	ll p,q,r,f,maxp,maxq,maxr;
	scanf("%lld%lld%lld%lld",&n,&p,&q,&r);
	for(i=0;i<n;i++)
	{
		scanf("%lld",&a[i]);
	}
	
	if(p>0&&q>0&&r>0)//如果都是正数,都乘最大的呗
	{
		f=p+q+r;
		sort(a,a+n);
		printf("%lld\n",f*a[n-1]);
	}
	else if(p<=0&&q<=0&r<=0)//如果都是负数,都乘以最小的呗
	{
		f=p+q+r;
		sort(a,a+n);
		printf("%lld\n",f*a[0]);
	}
	else{
		pp=a[0]*p;
		qq=a[0]*q+pp;
		rr=a[0]*r+qq;
		for(i=1;i<n;i++)
		{
			//pp表示从数组一开始到i,a[i]*p的最大值
			if(pp<a[i]*p)//如果pp小与此时的最新的,就变一下保留最优解
			{
				pp=a[i]*p;
			}
			else{
				pp=pp;///如果还是以前的大,就还用以前的呗
			}
			if(qq<pp+a[i]*q)//qq表示pp+a[i]*q
			{
				qq=pp+a[i]*q;
			}
			else{
				qq=qq;
			}
			if(rr<qq+a[i]*r)//rr表示qq+a[i]*r
			{
				rr=qq+a[i]*r;
			}
			else{
				rr=rr;
			}
		}
		printf("%lld\n",rr);//最后的rr就是最优解了,rr一直是p*ai+q*aj+r*ak的和
	}
	
}

其实这样就保证了 1 ≤ i ≤ j ≤ k ≤ n.
还不明白欢迎评论区提问啊!!!

 类似资料: