分块解决简单实践最优贸易简化(魔改)

C国有 n 座城市,编号是 1 到 n ,编号为 i 的城市有路到编号为 i+1 的城市(编号为 n 的城市没有路到其他的城市)。 C国幅员辽阔,各地的资源分布情况各不相同,这就导致了同一种商品在不同城市的价格不一定相同。买入价和卖出价始。 商人阿龙再次来到C国旅游。他还是想贩卖水晶赚取旅费,在某个城市买入,再另一个城市卖出。 他将从编号为 a 的城市到编号到 b 的城市。请你帮他算算,最多能赚多少钱。 注:他最多进行一次买入和一次卖出。

输入描述:
第一行两个整数n和m,表示n个城市和m个询问。
第二行2n个整数,表示n座城市水晶的买入和卖出的价格。
接下来m行,每行两个整数a,b,表示阿龙要从编号为a的城市到编号为b的城市(保证a<b)。

输出描述:
对于每个询问输出阿龙最多能赚多少钱。

本次如果数据量小,可以考虑枚举算法解决问题,对于每个城市都计算卖出价和买入价的差价,随着路程逐渐更新最低价。代码很容易实现( 输入部分略去)假设询问a到b范围内

#include<bits/stdc++.h>
int main()
{
int buy[n],sell[n];
int min=100000000,max=0;
for(int i=a,i<=b;i++)
{
if(buy[i]<min)
min=buy[i];
if(sell[i]-min>max)
max=sell[i]-min;
} 
return 0;
}

上面代码思路清晰是一个复杂度为o(n)的简单枚举算法

在遇到较大数据规模时,我们需要一些更好的方法去解决问题
所以我们提出了分的思想,对于每块的大小我们选取sqrt(n) 在主函数中我们计算没块的数据。只需记录一次
对与他询问的区间我们会面临一个问题这个区间可能有两个不完整的区域,对此为了方便我们对这两部分进行遍历,而对于没块只需存储其中最小值,区内最高收益,和区内最大值、

代码如下

#include<bits/stdc++.h>
int res;
int ma[n],mi[n],key[n];//数组下标代表其本身所代表组数的数据  key为当前组内本身能获得的最高利润
int job(int a,int b,int x,int a[],int b[])
{
int qq=a/x;//起点所在区
int ww=b/x;//终点所在区
if(qq==ww)
{int mi2=buy[a];
for(int i=a+1,i<=b;i++)
{
res=max(res,sell[i]-mi2);
mi=min(mi,buy[i]);
}
else(
int mi2=buy[a];
for(int i=a,i<(qq+1)*s)
{
res=max(res,sell[i]-mi2);
mi=min(mi,buy[i]);
}
for(int i=(qq+1)*s;i<=ww*s;i++)
{
res=max(max(key[x],res),ma[x]-mi2);
mi2=min(mi2,mi[x]);
}
for(int i=ww*s,i<=b,i++)
{
res=max(res,sell[i]-mi2);
mi=min(mi,buy[i]);
}
}


int main()
{
int buy[n],sell[n]int min=100000000,q;
res=0;
q=sqrt(n);
for(int i=0;i<=n;i++)
{int x=n/q;//x是当前所计算数据所属组数
key[x]=max(key[x],sell[i]-mi[x];
mi[x]=min(min[x],sell[i])
ma[x]=max(ma[a],buy[i]);
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值