ドラゴンボールレーダーダブルポインタ+ DPは、
あなたはそれがあなたとパールが発生を教えてくれる、パールレーダーを得ました。
ドラゴンボールレーダー画面は横軸の数、時間の各ウィンドウで、ドラゴンボール、いくつかのポイントの同じ種類のあなたが消えますドラゴンボール、ドラゴンボールが他の取得たびに軸の数があるでしょう。次の時間ウィンドウは、別の軸の数は、真珠を発生します。時間のn個の窓の合計、すなわち、n個のパールの合計です。
あなたはyは、軸0秒かかりますが、それはとり指すように点xから移動し、あなたは即座に移動すると仮定| XY |強。同時に、彼はパールも体力の一定量をとり掘りました。私はあなたが一緒にパールのすべての種類を集めることができ、物理的強度の最小の費用がどのくらい、お願いします。
ソリューション:
式Iは、コードを参照してください言わないだろう
、私は最短スペースは、その後、MLEにつながる、まだ実際に間違っていると思うし始めた言葉
は本当にZZ
ここでの主な発言の最適化
まず、私たちは順番にI-1層にすることに注意してください\(DIS(k)を<DIS (J)\) 私たちはJの$のDIS(K)が直線的に増加してi層の条件を満たすために最低限を見つける必要が成長している範囲の$大きいが
、ダブルポインタ極値考えることができる
コード:
//
#include<iostream>
#include<cstdio>
#include<stdio.h>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<queue>
#define ll long long
using namespace std;
#define maxnn 10005
ll f[55][maxnn];
ll w[55][maxnn];
struct node
{
ll x, y;
} mapp[55][maxnn];
int n,m,x;
bool cmp(node a,node b)
{
return a.x<b.x;
}
int main()
{
cin>>n>>m>>x;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
scanf("%lld",&mapp[i][j].x);
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
scanf("%lld",&mapp[i][j].y);
}
for(int i=1;i<=n;i++)
sort(mapp[i]+1,mapp[i]+1+m,cmp);
for(int j=1;j<=m;j++)
{
f[1][j]=abs(mapp[1][j].x-x)+mapp[1][j].y;
}
for(int i=2;i<=n;i++)
{
ll index=1;
ll ans=11111111100;
for(ll j=1;j<=m;j++)
{
f[i][j]=10000000000;
while(mapp[i][j].x>=mapp[i-1][index].x&&index<=m)
{
ans=min(ans,f[i-1][index]-mapp[i-1][index].x);
index++;
}
f[i][j]=min(ans+mapp[i][j].y+mapp[i][j].x,f[i][j]);
}
index=m;
ans=10000000000;
for(int j=m;j>=1;j--)
{
while(mapp[i][j].x<=mapp[i-1][index].x&&index>=1)
{
ans=min(ans,f[i-1][index]+mapp[i-1][index].x);
index--;
}
f[i][j]=min(ans+mapp[i][j].y-mapp[i][j].x,f[i][j]);
}
}
ll ans=11111111000;
for(int i=1;i<=m;i++)
ans=min(ans,f[n][i]);
cout<<ans;
}