sincerit 淘宝流量分配(动态规划)

在每年的淘宝“双十一”时,访问量都会暴涨,服务器的请求会被流量分配程序按照一定策略,分发给不同的进程去处理。有一类请求,有两个进程可以接受分发的请求,其中一个进程所在服务器的配置、网络传输性能等都要优于另一个进程。流量分发程序可以知道队列中每个任务的预计处理时间,每次都会尽可能将队列中预计处理时间更多的任务分配给性能更优的进程。
假设队列当前一共有 nn 个任务待分配,第 ii 个任务的预计处理时间为 a_i(1 \leq i \leq n)ai(1≤i≤n)。由于服务存在冷启动问题,越靠后的进程,预计处理时间越短。而队列中的 最后一个任务 因为比较特殊,预计处理时间和之前的任务 无关。即前 n-1n−1 个任务的预计处理时间满足 a_1 > a_2 > … > a_{n-1}a
1>a2>…>an−1。现在要从中选出一个任务列表,不能有任何两个任务在原队列中相邻。计算选出的任务队列预计处理时间之和的最大值。
输入格式
输入第一行有一个整数 n(1 \leq n \leq 10^{4})n(1≤n≤104),表示任务总数。
输入第二行有 nn 个整数 a_i(0 \leq a_i \leq 10^{4})ai(0≤ai≤104),表示每个任务的预计处理时间。
输出格式
输出一个整数,表示选出的任务的预计处理时间之和的最大值。
样例输入1 复制
5
4 3 2 1 5
样例输入2 复制
4
5 3 1 9
样例输出2 复制
14

题意是取一些数字加起来和最大,但是这些数字是不能相邻的
动态规划有忘了,还要继续练啊
大神的思路:B[i] = std::max(A[i] + std::max(B[i - 2], B[i - 3]), B[i - 1]);

#include <stdio.h>
#include <cstring>
const int N = 1e4+5;
long long dp[N]; // dp[i]表示到达第i个数时的最大值
// 转移方程 对于第i个数 num[i]
// dp[i] = max(max(dp[i-2], dp[i-3])+num[i], dp[i-1]);
// 初始值 dp[1] = num[1], dp[2] = num[2]>num[1]?num[2]:num[1]; 
long long num[N];
long long max(long long x, long long y) {
  return x > y ? x : y;
}
int main() {
  int n;
  while (~scanf("%d", &n)) {
    for (int i = 1; i <= n; i++) scanf("%lld", &num[i]);
    dp[0] = 0; 
    dp[1] = num[1]; 
    dp[2] = num[2];
    for (int i = 3; i <= n; i++) {
      dp[i] = max(max(dp[i-2], dp[i-3])+num[i], dp[i-1]);
    }
    if (n == 2) printf("%lld\n", dp[1]>dp[2]?dp[1]:dp[2]); 
    else printf("%lld\n", dp[n]);
  }
  // 没考虑 n = 2的时候 这种题目知道怎么做之后就这里要注意一些
  return 0;
}

猜你喜欢

转载自blog.csdn.net/sincerit/article/details/84885918