链接:http://acm.cs.ecnu.edu.cn/problem.php?problemid=1600
转移方程:dp[i+1][j+k] = min(dp[i+1][j+k],dp[i][j]+t); //从第i个关口,到第i+1个关口会与t个车相遇。
这里可以优化的。没优化也能过。就不优化了。。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <stack> using namespace std; const int INF = 0x3f3f3f3f; int dp[59][31009]; struct nod{ int stt,t; } re[309][309]; int d[309]; int zip(int k) { int a = k/10000,b=(k/100)%100,c=k%100; a-=6; return ((a*60)+b)*60+c; } int rezip(int k) { int a,b,c; c=k%60;k/=60; b=k%60;k/=60; a=k; return (a+6)*10000+b*100+c; } int main() { freopen("in.txt","r",stdin); int n,m;int a,b,c; scanf("%d%d",&n,&m); memset(dp,INF,sizeof(dp)); for(int i=0;i<m;i++) { scanf("%d%d%d",&a,&b,&c);a--; b=zip(b); re[a][d[a]].stt = b,re[a][d[a]].t = c+b; d[a]++; }dp[0][0] = 0;n--; for(int i=0;i<n;i++) { for(int j=i*300;j<=i*600;j++) { for(int k=300;k<=600;k++) { int t =0 ; for(int l=0;l<d[i];l++) if(re[i][l].t==j+k){ t++; }else{ if(re[i][l].stt<=j&&re[i][l].t<=j+k) continue; if(re[i][l].stt>=j&&re[i][l].t>=j+k) continue; t++; } dp[i+1][j+k] = min(dp[i+1][j+k],dp[i][j]+t); } } } int ans=INF,t; for(int i=n*300;i<=n*600;i++) if(dp[n][i]<ans) t = i,ans =dp[n][i]; printf("%d\n%06d\n",ans,rezip(t)); return 0; }