题目描述
z t x z 16 ztxz16 ztxz16生活的城市有 N × M N\times M N×M个景点,可以描述成一个 N × M N\times M N×M的矩形,每个景点有一个坐标 ( x , y ) ( 1 < = x < = N , 1 < = y < = M ) (x, y) (1 <= x <= N, 1 <= y <= 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| ∣x1−x2∣+∣y1−y2∣。
为了防止审美疲劳, 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;
}