【USACO 5.4.1】Canada Tour

题目大意

  给出一个序列,序列中的每个元素是一个字符串。然后输入哪些元素可以互相到达。计算可以到达城市最多这样的一条路径,从序列开始的元素到达序列末端元素,再从序列末端元素返回序列开始元素,这条路径中所到达的元素不能重复(除起点外)。序列最长是100.

题解

  明显我们可以发现这样的一件事:从起点到达终点和从终点到达起点并没有什么不同。

  所以,现在我们考虑两条从起点到达终点并且不相交的两条路径即可。

  我们现在考虑一条路径怎么做。显然是使用DP:f[目前到达元素i] = max{f[j | 从起点可以到达j并且j可到达i且j < i] + 1}, f[起点] = 1

  类似的。我们求两条路径也是差不多。f[第一条路径到达元素i][第二条路径到达元素j] = max{f[k | 同上][j], f[i][k | 同上]} + 1

  最后求答案的是再枚举那两个元素可以到达终点。算法复杂度是O(N3)

  至此,问题被完美地解决了。

  代码和上述表达有稍微差别。

/*
TASK:tour
LANG:C++
*/
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <string>

using namespace std;

int f[105][105], ans, n, v;
string s1, s2;
map<string, int> getid;
bool g[105][105];

int main()
{
    freopen("tour.in", "r", stdin);
    freopen("tour.out", "w", stdout);
    scanf("%d%d", &n, &v);
    for (int i = 0; i < n; ++i)
    {
        cin >> s1;
        getid[s1] = i;
    }
    memset(g, false, sizeof(g));
    while (v--)
    {
        cin >> s1 >> s2;
        int x = getid[s1], y = getid[s2];
        g[x][y] = g[y][x] = true;
    }
    memset(f, 0, sizeof(f));
    f[0][0] = 1;
    for (int k = 0; k < n; ++k)
        for (int i = 0; i <= k; ++i)
            for (int j = 0; j <= k; ++j)
            if (f[i][j] > 0){
                if (k != i && g[j][k]) f[i][k] = max(f[i][k], f[i][j] + 1);
                if (k != j && g[i][k]) f[k][j] = max(f[k][j], f[i][j] + 1);
            }
    ans = 1;
    for (int i = 0; i < n; ++i)
        if (g[i][n - 1])
        for (int j = 0; j < n; ++j)
            if (i != j && g[j][n - 1])
                ans = max(ans, f[i][j] + 1);
    printf("%d\n", ans);
    return 0;
}
时间: 2024-10-10 22:37:03

【USACO 5.4.1】Canada Tour的相关文章

【USACO 1.3.4】牛式

[題目描述 ] 下面是一个乘法竖式,如果用我们给定的那n个数字来取代*,可以使式子成立的话,我们就叫这个式子牛式. * * * x * * ---------- * * * * * * ---------- * * * * 数字只能取代*,当然第一位不能为0,况且给定的数字里不包括0. 注意一下在美国的学校中教的"部分乘积",第一部分乘积是第二个数的个位和第一个数的积,第二部分乘积是第二个数的十位和第一个数的乘积. 写一个程序找出所有的牛式. [格式] INPUT FORMAT: (f

【USACO 1.2.2】方块转换

[问题描述] 一块N x N(1<=N<=10)正方形的黑白瓦片的图案要被转换成新的正方形图案.写一个程序来找出将原始图案按照以下列转换方法转换成新图案的最小方式: 1:转90度:图案按顺时针转90度. 2:转180度:图案按顺时针转180度. 3:转270度:图案按顺时针转270度. 4:反射:图案在水平方向翻转(以中央铅垂线为中心形成原图案的镜像). 5:组合:图案在水平方向翻转,然后再按照1到3之间的一种再次转换. 6:不改变:原图案不改变. 7:无效转换:无法用以上方法得到新图案. 如

【USACO 2.3.4】货币系统

[描述] 母牛们不但创建了它们自己的政府而且选择了建立了自己的货币系统.由于它们特殊的思考方式,它们对货币的数值感到好奇. 传统地,一个货币系统是由1,5,10,20 或 25,50, 和 100的单位面值组成的. 母牛想知道有多少种不同的方法来用货币系统中的货币来构造一个确定的数值. 举例来说, 使用一个货币系统 {1,2,5,10,...}产生 18单位面值的一些可能的方法是:18x1, 9x2, 8x2+2x1, 3x5+2+1,等等其它. 写一个程序来计算有多少种方法用给定的货币系统来构

【USACO 2.3.3】零数列

[题目描述] 请考虑一个由1到N(N=3, 4, 5 ... 9)的数字组成的递增数列:1 2 3 ... N. 现在请在数列中插入“+”表示加,或者“-”表示减,“ ”表示空白(例如1-2 3就等于1-23),来将每一对数字组合在一起(请不要在第一个数字前插入符号). 计算该表达式的结果并判断其值是否为0. 请你写一个程序找出所有产生和为零的长度为N的数列. [格式] PROGRAM NAME: zerosum INPUT FORMAT 单独的一行表示整数N (3 <= N <= 9). O

【USACO 2.3.5】控制公司

[题目描述] 有些公司是其他公司的部分拥有者,因为他们获得了其他公司发行的股票的一部分.例如,福特公司拥有马自达公司12%的股票.据说,如果至少满足了以下三个条件之一,公司A就可以控制公司B了: 公司A = 公司B. 公司A拥有大于50%的公司B的股票. 公司A控制K(K >= 1)个公司,记为C1, ..., CK,每个公司Ci拥有xi%的公司B的股票,并且x1+ .... + xK > 50%. 给你一个表,每行包括三个数(i,j,p):表明公司i享有公司j的p%的股票.计算所有的数对(h

【USACO 1.4.2】时钟

[题目描述] 考虑将如此安排在一个 3 x 3 行列中的九个时钟: |-------| |-------| |-------| | | | | | | | |---O | |---O | | O | | | | | | | |-------| |-------| |-------| A B C |-------| |-------| |-------| | | | | | | | O | | O | | O | | | | | | | | | | |-------| |-------| |---

【USACO 1.4.1】铺放矩形块

[描述] 给定4个矩形块,找出一个最小的封闭矩形将这4个矩形块放入,但不得相互重叠.所谓最小矩形指该矩形面积最小. 所有4个矩形块的边都与封闭矩形的边相平行,图1示出了铺放4个矩形块的6种方案.这6种方案是仅可能的基本铺放方案.因为其它方案能由基本方案通过旋转和镜像反射得到. 可能存在满足条件且有着同样面积的各种不同的封闭矩形,你应该输出所有这些封闭矩形的边长. (分类注解:这里的分类依据可以视为是不同的面积计算公式.) [格式] INPUT FORMAT: (file packrec.in)

【USACO 1.2.1】挤牛奶

[问题描述] 三个农民每天清晨5点起床,然后去牛棚给3头牛挤奶.第一个农民在300时刻(从5点开始计时,秒为单位)给他的牛挤奶,一直到1000时刻.第二个农民在700时刻开始,在 1200时刻结束.第三个农民在1500时刻开始2100时刻结束.期间最长的至少有一个农民在挤奶的连续时间为900秒(从300时刻到1200时刻),而最长的无人挤奶的连续时间(从挤奶开始一直到挤奶结束)为300时刻(从1200时刻到1500时刻). 你的任务是编一个程序,读入一个有N个农民(1 <= N <= 5000

【USACO 3.1.5】联系

[描述] 奶牛们开始对用射电望远镜扫描牧场外的宇宙感兴趣.最近,他们注意到了一种非常奇怪的脉冲调制微波从星系的中央发射出来.他们希望知道电波是否是被某些地外生命发射出来的,还是仅仅是普通的的星星发出的. 帮助奶牛们用一个能够分析他们在文件中记下的记录的工具来找到真相.他们在寻找长度在A到B之间(含)在每天的数据文件中重复得最多的比特序列 (1 <= A <= B <= 12).他们在找那些重复得最多的比特序列.一个输入限制告诉你应输出多少频率最多的序列. 符合的序列可能会重叠,并且至少出