链接: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;
}