USACO Canada Tour
这道题的意思是平面上有一些点, 这些点从西向东分布,现在选一条路线从最西走向最东 在反过来走, 问选择一条路线走尽可能多的城市, 我们可以将这个问题看成两个人从最西边走向最东边, 定义f[i][j]为1走向i而2走向j的最大城市数,f[j][i] = f[i][j] = max(f[i][k]) + 1, 1<=k<j, 结果就是max(f[i][N]), 代码如下:
/* ID: m1500293 LANG: C++ PROG: tour */ #include <cstdio> #include <algorithm> #include <cstring> #include <map> #include <string> #include <iostream> using namespace std; int N, V; //顶点个数 以及 航线个数 int d[110][110]; int f[110][110]; int main() { freopen("tour.in", "r", stdin); freopen("tour.out", "w", stdout); cin>>N>>V; map<string, int> rep; int num = 1; for(int i=0; i<N; i++) { string str; cin>>str; if(rep.find(str) == rep.end()) rep[str] = num++; } for(int i=0; i<V; i++) { string u, v; cin>>u>>v; d[rep[u]][rep[v]] = 1; d[rep[v]][rep[u]] = 1; } f[1][1] = 1; for(int i=1; i<=N; i++) for(int j=i+1; j<=N; j++) { f[i][j] = -0x3fffffff; for(int k=1; k<j; k++) //f[i][k] - > f[i][j] if(d[k][j] && f[i][k]>0 && f[i][k]>f[i][j]) f[i][j] = f[i][k]; f[j][i] = ++ f[i][j]; } int ans = 1; for(int i=1; i<N; i++) //f[i][N] d[i][N] if(d[i][N] && f[i][N]>ans) ans = f[i][N]; printf("%d\n", ans); return 0; }