[Jzoj] 3490. 旅游

题目描述

z t x z 16 ztxz16 ztxz16生活的城市有 N × M N\times M N×M个景点,可以描述成一个 N × M N\times M N×M的矩形,每个景点有一个坐标 ( x , y ) ( 1 &lt; = x &lt; = N , 1 &lt; = y &lt; = M ) (x, y) (1 &lt;= x &lt;= N, 1 &lt;= y &lt;= M) (x,y)(1<=x<=N,1<=y<=M)以及美观度 A [ x ] [ y ] A[x][y] A[x][y]和观赏所需的时间 B [ x ] [ y ] B[x][y] B[x][y],从一个景点 ( x 1 , y 1 ) (x1, y1) (x1,y1)走到另一个景点 ( x 2 , y 2 ) (x2, y2) (x2,y2)需要时间为它们之间的曼哈顿距离: ∣ x 1 − x 2 ∣ + ∣ y 1 − y 2 ∣ |x1 - x2| +|y1 - y2| x1x2+y1y2

为了防止审美疲劳, z t x z 16 ztxz16 ztxz16希望观赏的景点的的美观度是严格上升的,由于不想太早回家码代码, z t x z 16 ztxz16 ztxz16希望旅游的总时间尽可能长。

题目解析

这题数据很水

按照美观度 A A A升序,由于美观度是严格上升的,所以令同一美观度为一个区间,往下推即可。

代码

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,m,l,r,cnt,ans;
ll f[1000005],mapa[1005][1005];
struct A
{
	ll x,y,a,b,id;
}a[1000005];
bool cmp(A a,A b) {return a.a==b.a?a.id<b.id:a.a<b.a;}
ll read()
{
	ll x=0;char c=getchar();
	while(c<'0'||c>'9') c=getchar();
	while(c>='0'&&c<='9') x=x*10+c-48,c=getchar();
	return x;
}
int main()
{
	n=read();m=read();
	for(int i=1;i<=n;i++)
	 for(int j=1;j<=m;j++)
	  mapa[i][j]=read();
	for(int i=1;i<=n;i++)
	 for(int j=1,k;j<=m;j++)
	 {
	   k=read();
	   if(mapa[i][j]==0&&k==0) continue;
	   a[++cnt].a=mapa[i][j];a[cnt].b=k;a[cnt].x=i;a[cnt].y=j;a[cnt].id=(i-1)*n+j;
	 }
	sort(a+1,a+1+cnt,cmp);
	l=1;r=0;
	for(int i=1;i<=cnt;i++)
	 if(a[i].a==a[1].a)
	  f[i]=a[i].b,r++;
	 else break;
	for(int i=r+1;i<=cnt;i++)
	{
	  if(a[i].a!=a[r+1].a)
	   l=r+1,r=i-1;
	  for(int j=l;j<=r;j++)
	   f[i]=max(f[i],f[j]+abs(a[i].x-a[j].x)+abs(a[i].y-a[j].y)+a[i].b);
	  ans=max(ans,f[i]);
	}
	cout<<ans;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值