1. 程式人生 > >計蒜客 淘寶流量分配 3-7

計蒜客 淘寶流量分配 3-7

題目:

在每年的淘寶“雙十一”時,訪問量都會暴漲,伺服器的請求會被流量分配程式按照一定策略,分發給不同的程序去處理。有一類請求,有兩個程序可以接受分發的請求,其中一個程序所在伺服器的配置、網路傳輸效能等都要優於另一個程序。流量分發程式可以知道佇列中每個任務的預計處理時間,每次都會盡可能將佇列中預計處理時間更多的任務分配給效能更優的程序。

假設隊列當前一共有 nn 個任務待分配,第 ii 個任務的預計處理時間為 a_i(1 \leq i \leq n)ai(1in)。由於服務存在冷啟動問題,越靠後的程序,預計處理時間越短。而佇列中的 最後一個任務 因為比較特殊,預計處理時間和之前的任務 無關

。即前 n-1n1 個任務的預計處理時間滿足 a_1 > a_2 > ... > a_{n-1}a1>a2>...>an1。現在要從中選出一個任務列表,不能有任何兩個任務在原佇列中相鄰。計算選出的任務佇列預計處理時間之和的最大值。

輸入格式

輸入第一行有一個整數 n(1 \leq n \leq 10^{4})n(1n104),表示任務總數。

輸入第二行有 nn 個整數 a_i(0 \leq a_i \leq 10^{4})ai(0ai104),表示每個任務的預計處理時間。

輸出格式

輸出一個整數,表示選出的任務的預計處理時間之和的最大值。

樣例輸入1

5
4 3 2 1 5

樣例輸出1

11

樣例輸入2

4
5 3 1 9

樣例輸出2

14
思路:這道題的大致意思是給你一個遞減序列(最後一個除外),然後找一個子序列,子序列中的元素在原序列不相鄰,求子序列的最大值。

可以用動態規劃,dp[i]=max(dp[i],dp[j]+a[i]),1<=1j<i-1;dp[i]表示原序列前i個最大值;

#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
#define maxn 10000+5
int a[maxn],dp[maxn];
int main()
{
	int n,ans=0;
	scanf("%d", &n);
	for (int i = 1; i <= n; i++)
		scanf_s("%d", &a[i]);
	dp[1] = a[1]; dp[2] = a[2];
	ans = max(dp[1], dp[2]);
	for (int i = 3; i <= n; i++)
	{
		for(int j=1;j<i-1;j++)
		dp[i] = max(dp[j] + a[i],dp[i]);
		ans = max(dp[i], ans);
	}
	printf("%d", ans);
	return 0;
}