神题呀,我们观察到行走的方式一定是一条链+若干条环.
然后环可以看成是一对括号,所以来一个基于括号序的 DP.
code:
#include <bits/stdc++.h> #define ll long long #define N 3040 #define setIO(s) freopen(s".in","r",stdin) using namespace std; int n,T; int l0[N],l1[N],r0[N],r1[N],f[N][N]; int main() { // setIO("input"); int i,j; scanf("%d%d",&n,&T); memset(f,0x3f,sizeof(f)); for(i=1;i<=n;++i) scanf("%d%d%d%d",&l0[i],&r1[i],&r0[i],&l1[i]); f[0][0]=0; for(i=1;i<=n;++i) { for(j=0;j<=n;++j) { if(j) { f[i][j]=min(f[i][j],f[i-1][j-1]+(j-1)*2*T+r0[i]+r1[i]); f[i][j]=min(f[i][j],f[i-1][j]+j*2*T+r0[i]+l1[i]); } f[i][j]=min(f[i][j],f[i-1][j]+j*2*T+l0[i]+r1[i]); f[i][j]=min(f[i][j],f[i-1][j+1]+(j+1)*2*T+l0[i]+l1[i]); } for(j=1;j<=n;++j) f[i][j]=min(f[i][j],f[i][j-1]+r0[i]+r1[i]); for(j=n-1;j>=0;--j) f[i][j]=min(f[i][j],f[i][j+1]+l0[i]+l1[i]); } printf("%d",f[n][0]+(n+1)*T); return 0; }