题解:P14424 [JOISC 2014] 邮戳收集 / Collecting Stamps
george0929 · · 题解
经过一个打卡点有四种方式:
考虑在东向电车行走的路线,可以跳过若干打卡点不走,其余走
注意
将
简化状态,由于在上面只能往左走,因此只有存在没有匹配的
令
转移时,可以选择
前缀和优化可以做到
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int n,T;
int f[3005][3005];
int u[3005],v[3005],d[3005],e[3005];
void upd(int &x,int y){
x=min(x,y);
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n>>T;
for(int i=1;i<=n;i++){
cin>>u[i]>>v[i]>>d[i]>>e[i];
}
memset(f,0x3f,sizeof(f));
f[1][0]=T+u[1]+v[1];
for(int i=1;i<=n;i++){
f[1][i]=T+(d[1]+v[1])*i;
}
f[1][1]=T+d[1]+v[1];
e[n+1]=d[n+1]=0x3f3f3f3f;
for(int i=1;i<=n;i++){
for(int j=0;j<=n;j++){
upd(f[i+1][j],f[i][j]+u[i+1]+v[i+1]+2*j*T+T);
if(j>0) upd(f[i+1][j],f[i][j]+d[i+1]+e[i+1]+2*j*T+T);
}
int mn=f[i][0]+d[i+1]+v[i+1];
for(int j=1;j<=n;j++){
upd(f[i+1][j],mn+T);
mn=min(mn,f[i][j]+2*j*T);
mn+=d[i+1]+v[i+1];
}
mn=f[i][n]+e[i+1]+u[i+1]+2*n*T;
for(int j=n-1;j>=0;j--){
upd(f[i+1][j],mn+T);
mn=min(mn,f[i][j]+2*j*T);
mn+=e[i+1]+u[i+1];
}
}
cout<<f[n+1][0]<<"\n";
}