小明有n(1≤n≤2000)个美味的食物,他想卖掉它们来赚钱。这些食物放在一些箱子里,它们有些有趣的特性:
(1)这些食物被编号1~n,每一天小明可以从这排箱子的头部或者尾部取出食物去卖;
(2)这些食物放的越久,年龄越大,价值越大,食物i有一个初始的价值V(i);
(3)放了a天后,年龄为a,食物最终价值为V(i)xa。
给定每一个食物的初始价值V(i),请求出小明卖掉它们后可以获得的最大价值,第一天出售的食物年龄为1,此后每增加一天食物的年龄就加1。
小明有n(1≤n≤2000)个美味的食物,他想卖掉它们来赚钱。这些食物放在一些箱子里,它们有些有趣的特性:
(1)这些食物被编号1~n,每一天小明可以从这排箱子的头部或者尾部取出食物去卖;
(2)这些食物放的越久,年龄越大,价值越大,食物i有一个初始的价值V(i);
(3)放了a天后,年龄为a,食物最终价值为V(i)xa。
给定每一个食物的初始价值V(i),请求出小明卖掉它们后可以获得的最大价值,第一天出售的食物年龄为1,此后每增加一天食物的年龄就加1。
第1行:一个整数n;
第i+l行:每行食物i的初始价值V(i)。
1行:小明最终可以获得的最大价值。
5 1 3 1 5 2
43
小明出售这些食物(初始价值1,3,1,5,2)的顺序为:第一天卖掉1个,第二天卖掉5个,第三天卖掉2个,第四天卖掉3个,第五天卖掉4个,获得最大的价值1x1+2x3+3x3+4x1+5x5=43。
#include <stdio.h>
#define MAX_N 2000
int value[MAX_N], dp[MAX_N];
int max(int x, int y)
{
return x > y ? x : y;
}
int solve(int n)
{
int i, j, age;
for (i = 0; i < n; ++i)
{
dp[i] = n * value[i];
}
for (i = n - 2; i >= 0; --i)
{
for (j = i + 1; j < n; ++j)
{
age = n - j + i;
dp[j] = max(value[i] * age + dp[j],
value[j] * age + dp[j - 1]);
}
}
return dp[n - 1];
}
int main(int argc, char const *argv[])
{
int n, i;
scanf("%d", &n);
for (i = 0; i < n; ++i)
{
scanf("%d", value + i);
}
printf("%d\n", solve(n));
return 0;
}
#include <bits/stdc++.h> using namespace std; int main() { int n,res=0; cin>>n; int v[n]; for(int i=0;i<n;i++) cin>>v[i]; int head = 0; int tail = n - 1; int sum = 0; int day = 1; while (head <= tail) { if (v[head] < v[tail]) sum += day * v[head++]; else sum += day * v[tail--]; day++; } cout<<sum<<endl; return 0; }
用两个指针指向头尾,每次都取较小值加上去。因为要获得最大值而且每次只能操作头尾,所以较大的值放在后面计算肯定会取得最优解。
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int[] v = new int[n]; for (int i = 0; i < n; i++) { v[i] = sc.nextInt(); } int head = 0; int tail = n - 1; int sum = 0; int day = 1; while (head <= tail) { if (v[head] < v[tail]) { sum += day * v[head++]; } else { sum += day * v[tail--]; } day++; } System.out.println(sum); } }
//java双端队列 import java.util.*; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); // 注意 hasNext 和 hasNextLine 的区别 while (in.hasNextInt()) { // 注意 while 处理多个 case int a = in.nextInt(); Deque<Integer> deque = new LinkedList<>(); for(int i=0;i<a;i++) deque.offerLast(in.nextInt()); System.out.println(caculate(deque)); } } public static int caculate(Deque<Integer> deque){ int sum = 0,day = 1; while(!deque.isEmpty()){ if(deque.peekFirst() < deque.peekLast()){ sum += day * deque.pollFirst(); day ++; }else{ sum += day * deque.pollLast(); day ++; } } return sum; } }
#include <iostream> using namespace std; int main () { int n; cin>>n; int *p; p=new int[n]; for(int i=0;i<n;i++) { cin>>p[i]; } int *q; q=new int[n]; int i=0,j=n-1,k=0; while(i<=j) { if(p[i]<=p[j]) { q[k]=p[i]; k++; i++; } else { q[k]=p[j]; k++; j--; } } int val=0; for(int i=0;i<n;i++) { val+=q[i]*(i+1); } cout<<val; return 0; }