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;
}

 

posted @ 2016-02-05 22:20  xing-xing  阅读(223)  评论(0编辑  收藏  举报