洛谷 P1073 最优贸易

1.分析

这道题目做法有很多,作为一个初学者,还是用深搜来解答。上课老师提示过有两个剪枝条件

  • 最小价格没有改变则退出
  • 最大利润没有改变则退出

所以在写深搜的时候,需要记录一下最小价格和最大利润。

洛谷的题解第一名采取了深搜加动态规划的方式,他的DP思路和我们老师上课提示过的很相似。只不过他的代码中,记录最大利润的数组、记录最小价格的数组都可以被优化掉 ,虽然算法题不需要考虑空间复杂度

2.AC代码

#include <iostream>
#include <algorithm>
#include <stdlib.h>
#include <cstring>
#include <stdio.h>
#include<vector>
using namespace std;
#define MAX 1000000

int n,m;
vector<int> g[100001];
int profit[100001];// 到 第i个城市时的最大利润

int Price[100001];
int minPri;


void dfs(int now,int pre,int min_price)
{
    int flag=1;
    // min_price=min(min_price,Price[now]);
    if(min_price>Price[now])
    {
        flag=0;
        min_price=Price[now];
    }

    int a=max(profit[pre],Price[now]-min_price);
    if(a>profit[now])
    {
        flag=0;
        profit[now]=a;
    }
    if(flag) return;
    for (int i = 0; i < g[now].size(); i++)
    {
        dfs(g[now][i],now,min_price);
    }
    
}


int main()
{   int a;
    int i;
    int x,y;
    scanf("%d %d",&n,&m);

    
    for ( i = 1; i <= n; i++)
    {
        scanf("%d",&Price[i]);
    }
    for ( i = 1; i <= m; i++)
    {
        scanf("%d %d %d",&x,&y,&a);
        g[x].push_back(y);
        if(a==2)
        {
            g[y].push_back(x);
        }
    }
    dfs(1,0,MAX);
    cout<<profit[n]<<endl;
    
}

我这里的代码并没有优化掉记录最大值的数组。如果保留了这个最大值的数组,就更有动态规划的感觉了。

3.反思

这道题目关键是如何剪枝/DP。

  • 因为售出价格可能在将来出现,所以我们总是希望购入价格尽可能地小。所以当最小价格没有更好的改进的时候,这个点就没有那么好了。
  • 其次,如果购入价格没有变的更低的话,我们需要考虑利润了。如果利润更好,说明这个点是有进一步深搜的价值的。
  • 感觉像是以是否在当前城市卖出为分界。
    • 如果在当前城市卖出,那么说明在当前城市所获得的利润,比之前的利润都要高。可以记录一下当前城市所获得的利润,然后继续向下深搜,看有没有更好的利润。
    • 如果不在当前城市卖出,说明最低价格更新了,我们可以向下面的城市看看有无更高的价格让我们出售。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值