[NOIP2018][낙곡P5017] 나룻배[DP]
14056 단어 dp
제목 대의:
제목 링크:https://www.luogu.org/problemnew/show/P5017nn이 있는데 각각 t1∼tnt1\sim t_nt1∼tn의 시간에 도착하면 한 대의 나룻배는 이들을 다른 곳으로 보내야 한다. 나룻배는 한 번 mm의 시간 단위를 왕복해야 한다.이 사람들 최대한 빨리 보내달라고.
아이디어:
틀림없이 먼저 ttt를 정렬할 수 있을 것이다.우리는 한 사람이 도착한 후에 발차하는 것은 단지 두 가지 상황일 뿐이라는 것을 안다.
먼저 s[i][j]s[i][j]s[j][j]를 미리 처리할 수 있으며, iii개인이 jjj개인과 같은 차를 타는 대기 시간을 나타낸다.그러면 s[i] [j] = ∑j = 1 n ∑i = 1 j - 1 ∑k = i j - 1 t j - t ks [i] [j] =\sum^ {n}{j=1}\sum^{j-1}_{i=1}\sum^{j-1}_{k=i}t_j-t_ks[i][j]=j=1∑ni=1∑j-1k=i∑j-1tj-1tj-3tk 그러면 f[i][j]f[i][j][j]는 ii i가 도착하면 출발하고 ii i는 j 분을 기다리는 최소 대기 시간을 나타낸다.그러면 반드시 jjj를 일일이 열거해야 한다. 이것은 전 jjj 개인이 이미 목적지에 도착했다는 것을 의미한다.그러면 iii 개인이 도착했을 때 나룻배가 돌아왔다면 바로 출발할 수 있다(즉 ii 개인의 대기시간은 0.00).이때 f[i][0] = min(f[i][0], f[j][k] + s[j+1] [i]) f[i][0]]=min(f[i]]]][0], f[j][k]+s[j+1][i]) f[i][0]]]=min(f[i][0], f[j][k]+s[j+1][i]) 중 kkkk는 제jj 개인이 기다리는 시간을 나타낸다.그러면 ii i 개인이 도착해서 페리카가 돌아오지 않으면 ii 개인이 기다리는 시간은 w = t j + k + m - 6 - t i w=tj+k+m-t_i w=tj+k+m - ti 중 tj+k+m tj+k+m tj+k+m는 나룻배가 돌아오는 시간이다.그러면 f [i] [w] = m in(f[i] [w], f [j] [k] + s [j + 1] [i] + (i) + (i j) w w f[i] [w] [w] [w] f[i] [w] [w] f[j] [k] + s [j+1] [i] + (i] + (i] + (i] + (i] + (i) + (i- j) + (i-j) * w) f [i] [w] [w] [w] [w] [w] f[i] [w] [w] f[[[j] [j] [j] + s] + s+ j + i] [j]++ i(j] i]++ ii) + ii(w) f[w] [w] [w] + if[n][i])(i=0∼m)min(f[n][i])(i=0\sim m)min(f[n][i])(i=0∼m)시간 복잡도 O(n2m)O(n^2m)O(n2m)로 본제를 넘기기에 충분하다.
코드:
#include
#include
#include
using namespace std;
const int N=510;
const int M=210;
const int Inf=2e9;
int n,m,ans,w,t[N],f[N][M],s[N][N];
int main()
{
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
scanf("%d",&t[i]);
sort(t+1,t+1+n);
for (int j=1;j<=n;j++)
for (int i=1;i<j;i++)
for (int k=i;k<j;k++)
s[i][j]+=t[j]-t[k];
memset(f,0x3f3f3f3f,sizeof(f));
t[0]=-Inf;
for (int i=0;i<=m;i++) //
{
f[0][i]=0;
f[1][i]=i;
}
for (int i=2;i<=n;i++)
for (int j=0;j<i;j++)
for (int k=0;k<=m;k++)
{
w=t[j]+k+m-t[i];
if (w>0)
f[i][w]=min(f[i][w],f[j][k]+s[j+1][i]+(i-j)*w);
else
f[i][0]=min(f[i][0],f[j][k]+s[j+1][i]);
}
ans=Inf;
for (int i=0;i<=m;i++)
ans=min(ans,f[n][i]);
printf("%d
",ans);
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
【경쟁 프로 전형적인 90문】008의 해설(python)의 해설 기사입니다. 해설의 이미지를 봐도 모르는 (이해력이 부족한) 것이 많이 있었으므로, 나중에 다시 풀었을 때에 확인할 수 있도록 정리했습니다. ※순차적으로, 모든 문제의 해설 기사를 들어갈 예정입니다. 문자열...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.