-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathCRSCNTRY.cs
66 lines (55 loc) · 2.39 KB
/
CRSCNTRY.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
using System;
// https://www.spoj.com/problems/CRSCNTRY/ #dynamic-programming-2d
// Finds out how many times Tom can creep on Agnes if he chooses his race card correctly.
public sealed class CRSCNTRY
{
private readonly int _agnesCheckpointCount;
private readonly int[] _agnesCheckpoints;
public CRSCNTRY(int agnesCheckpointCount, int[] agnesCheckpoints)
{
_agnesCheckpointCount = agnesCheckpointCount;
_agnesCheckpoints = agnesCheckpoints;
}
public int MostCheckpointOverlaps { get; set; }
// Since Tom can run as fast or slow as he needs to, this is longest common subsequence:
// https://en.wikipedia.org/wiki/Longest_common_subsequence_problem
public void ConsiderNewRaceCard(int raceCardCheckpointCount, int[] raceCardCheckpoints)
{
if (raceCardCheckpointCount <= MostCheckpointOverlaps)
return; // Not enough checkpoints to even bother trying.
int[,] mostCheckpointOverlaps = new int[_agnesCheckpointCount + 1, raceCardCheckpointCount + 1];
for (int r = 1, ac = 0; r <= _agnesCheckpointCount; ++r, ++ac)
{
for (int c = 1, rcc = 0; c <= raceCardCheckpointCount; ++c, ++rcc)
{
mostCheckpointOverlaps[r, c] = _agnesCheckpoints[ac] == raceCardCheckpoints[rcc]
? 1 + mostCheckpointOverlaps[r - 1, c - 1]
: Math.Max(mostCheckpointOverlaps[r - 1, c], mostCheckpointOverlaps[r, c - 1]);
}
}
int result = mostCheckpointOverlaps[_agnesCheckpointCount, raceCardCheckpointCount];
if (MostCheckpointOverlaps < result)
{
MostCheckpointOverlaps = result;
}
}
}
public static class Program
{
private static void Main()
{
int remainingTestCases = int.Parse(Console.ReadLine());
while (remainingTestCases-- > 0)
{
int[] agnesCheckpoints = Array.ConvertAll(Console.ReadLine().Split(), int.Parse);
var solver = new CRSCNTRY(agnesCheckpoints.Length - 1, agnesCheckpoints);
int[] raceCardCheckpoints;
while ((raceCardCheckpoints = Array.ConvertAll(
Console.ReadLine().Split(), int.Parse))[0] != 0)
{
solver.ConsiderNewRaceCard(raceCardCheckpoints.Length - 1, raceCardCheckpoints);
}
Console.WriteLine(solver.MostCheckpointOverlaps);
}
}
}