牛客网暑期ACM多校训练营(第二场)D-money

链接:https://www.nowcoder.com/acm/contest/140/D
来源:牛客网
 

题目描述

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
5
9 10 7 6 8

输出

3 4

题意:

    你会沿途经过n个商店,每个商店对唯一一件的物品有不同的价值标称a[i],你身上最多只能带一件物品,求当你走到终点的时候身上的最大价值和最小的交易次数

思路:

  比赛的时候用的DP过的,开一个二维dp[i][0/1]数组,第一维保存当前位置,第二维保存当前是否有物品,

  然后data数组保存每个商店物品价格,你可以轻易的想到你当前的状态只由上一个商店转移过来,

即dp[i][0]=max(dp[i-1][0],dp[i-1][1]+data[i]),

   dp[i][1]=max(dp[i-1][0]-data[i],dp[i-1][1]);

然后flag[i][0/1]表示最小的交易次数

题解给出了另一种做法:贪心

即如果data[i]=data[i+1];那么第i+1个商店就没有用,买入卖出都不会影响,

   如果a[i]<a[i+1],那么离开第i个商店的时候身上一定要有物品,

   如果a[i]>a[i+1],那么离开第i个商店的时候身上一定要没物品,

那么答案就是\sum_{i=1}^{n-1}max(data[i+1]-data[i],0)

最小的交易次数就是数组上升沿的数目*2

实际比赛时,算是综合了两种方法吧

#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
#include <algorithm>
 
#define inf 0x3f3f3f3f
 
using namespace std;
 
const int maxn = 1e5+7;
 
long long data[maxn];
 
long long dp[maxn][2];//当前位置/当前状态/
 
int main()
{
    int t;
    int n;
    int flag;
    int ans;
    scanf("%d",&t);
    for (int cases = 1; cases <= t ; ++cases)
    {
        scanf("%d",&n);
        flag=0;
        ans=0;
        memset(dp,0,sizeof(dp));
        scanf("%lld",&data[0]);
        scanf("%lld",&data[1]);
        if(data[1]>data[0])
        {
            flag=1;
            ans=1;
        } else
        {
            flag=0;
        }
        for (int i = 2; i < n; ++i)
        {
            scanf("%lld",&data[i]);
            if(data[i]>data[i-1])
            {
                if(flag==0)
                {
                    ans++;
                }
                flag=1;
            } else if(data[i]<data[i-1])
            {
                flag=0;
            }
        }
        dp[0][0]=0;
        dp[0][1]=-data[0];
        for (int i = 1; i < n ; ++i)
        {
            dp[i][0]=max(dp[i-1][0],dp[i-1][1]+data[i]);
            dp[i][1]=max(dp[i-1][0]-data[i],dp[i-1][1]);
        }
        printf("%lld %d\n",dp[n-1][0],ans*2);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/leper_gnome/article/details/81169284
今日推荐