1. 程式人生 > >牛客網暑期ACM多校訓練營(第二場) D: money

牛客網暑期ACM多校訓練營(第二場) D: money

White Cloud has built n stores numbered from 1 to n.
White Rabbit wants to visit these stores in the order from 1 to n.
The store numbered i has a price a[i] representing that White Rabbit can spend a[i] dollars to buy a product or sell a product to get a[i] dollars when it is in the i-th store.
The product is too heavy so that White Rabbit can only take one product at the same time.
White Rabbit wants to know the maximum profit after visiting all stores.
Also, White Rabbit wants to know the minimum number of transactions while geting the maximum profit.
Notice that White Rabbit has infinite money initially.

輸入描述:

The first line contains an integer T(0<T<=5), denoting the number of test cases.
In each test case, there is one integer n(0<n<=100000) in the first line,denoting the number of stores.
For the next line, There are n integers in range [0,2147483648), denoting a[1..n].

輸出描述:

For each test case, print a single line containing 2 integers, denoting the maximum profit and the minimum number of transactions.

示例1

輸入

1
5
9 10 7 6 8

輸出

3 4

題意:

給你一個[1,n]的商店順序,你只能從1-n,你可以在每個商店選擇買東西或者賣東西,買賣的價錢就是商店的權值,求最多大利潤和最小的運算元

思路:

就是一個簡單的dp,每次記錄前面的sell最優和buy最優

9 10 7 6 8
buy -9 -10 -6 -5 -7
sell 0 1 -2 0 3
bmax -9 -9 -6 -5 -5
smax 0 1 1 1 3

如圖所示,對於每一件商品,都維護smax和bmax的值,下一次的buy值和sell值有smax和bmax得到最後得到的smax就只最大利益

而對於運算元可以類似

#include <iostream>
#include <string.h>
using namespace std;
#define ll long long
ll dp[100005][2];
int main() {
    ios::sync_with_stdio(false);
    int T;
    cin >> T;
    for (int i = 1; i <= T; i ++) {
        int n;
        cin >> n;
        int x;
        cin >> x;
        memset(dp, 0, sizeof(dp));
        ll bmax, smax;
        bmax = (-1) * x;
        smax = 0;
        int ds = 0, db = 1;
        for (int j = 2, x; j <= n; j ++) {
            cin >> x;
            dp[j][0] = smax - x;//buy
            dp[j][1] = bmax + x;//sell
            if (smax < dp[j][1]) {
                ds = db + 1;//更新sell的運算元
                smax = dp[j][1];//更新smax
            }
            if (bmax < dp[j][0]) {
                db = ds + 1;//更新buy的運算元
                bmax = dp[j][0];//更新bmax
            }
        }
        cout << smax << " " << ds <<endl;
    }
    return 0;
}