LOJ #2878. 「JOISC 2014 Day2」邮戳拉力赛 动态规划+括号序列

神题呀,我们观察到行走的方式一定是一条链+若干条环.  

然后环可以看成是一对括号,所以来一个基于括号序的 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;
}

  

猜你喜欢

转载自www.cnblogs.com/guangheli/p/12381076.html