中大省赛试机题【环形最大连续和】

题目:http://soj.me/index.php

题意:给一连串的数字, 组成一个环,找出其最大的连续和.

解题思路:

  如果不是环,直接用O(n)的贪心算法求出最大连续和.

  所以这题可以分两种情况,先设第一个数是起点,可以当作环的断点,如果最大连续程没有跨越这个断点, 那么就是上面所说的情况,直接可求得.

  如果跨越这个断点,那么,这个最大连续和里必定包含A[1] 和 A[N],也就是始末点.这样,可以简单地算出包括这两点的最大连续和了.

  用一个DP1[i] 来记录1...i点的最大连续和, DP2[i]表示i...N的最大连续和, 当然这两个连续必需分别与1和N点连接的.

  枚举每个i, 找出最大的 DP1[i] + DP2[i + 1], 其实就是枚举断点.

  可惜现场试机时没有用上long long, 返回结果wa.回来之后才找出中大oj提交AC了, 一直没有进过中大OJ, 今晚第一次在进入, 首页很喜欢(动漫迷).

#include <iostream>

#include <cstdio>



using namespace std;



const int MAX = 100000 + 10;

const long long MINF = 0x8000000000000000;

long long D[MAX];

long long DP1[MAX];

long long DP2[MAX];

long long Ans;



long long Max(long long a, long long b)

{

	return a > b ? a : b;

}

int main()

{

	freopen("in.txt", "r", stdin);

	int N;

	int T;

	int i, j;

	long long sum, max;

	scanf("%d", &T);

	while(T--)

	{

		scanf("%d", &N);

		max = MINF;

		sum = 0;

		for(i = 1; i <= N; ++i)

		{

			scanf("%lld", &D[i]);

			sum += D[i];

			if(sum > max)

				max = sum;

			if(sum < 0)

				sum = 0;

		}

		Ans = max;

		DP1[1] = sum = max = D[1];

		for(i = 2; i <= N; ++i)

		{

			sum += D[i];

			if(sum > max)

				DP1[i] = max = sum;

			else

				DP1[i] = max;

		}

		DP2[N] = sum = max = D[N];

		for(i = N - 1; i >= 1; --i)

		{

			sum += D[i];

			if(sum > max)

				DP2[i] = max = sum;

			else

				DP2[i] = max;

		}

		max = MINF;

		for(i = 1; i < N; ++i)

		{

			max = Max(max, DP1[i] + DP2[i + 1]);

		}

		if(max > Ans)

			Ans = max;

		printf("%lld\n", Ans);

	}

	return 0;
}
//驸加C题AC代码, 但用时2sec, 证明算法没有什么价值, 无视之
1 #include <iostream>

2 #include <cstdio>

3 #include <queue>

4 #include <cstring>

5 #include <vector>

6

7 using namespace std;

8

9 const int MAX = 500 + 10;

10 const int INF = 0x7f7f7f7f;

11 char Map[MAX][MAX];

12 int Dict[MAX][MAX];

13 int DX[] = {0, 1, -1, 0};

14 int DY[] = {1, 0, 0, -1};

15 int N, M;

16

17 struct Coord

18 {

19 bool operator == (Coord &t)

20 {

21 if(t.x == x && t.y == y)

22 return true;

23 return false;

24 }

25 int x;

26 int y;

27 };

28

29 struct comp

30 {

31 bool operator () (const Coord a, const Coord b)

32 {

33 return Dict[a.x][a.y] > Dict[b.x][b.y];

34 }

35 };

36

37 bool isValid(Coord &a)

38 {

39 if(a.x >= 0 && a.x < N && a.y >= 0 && a.y < M)

40 return true;

41 return false;

42 }

43

44 int solve(const Coord &start, const Coord &end)

45 {

46 int i;

47 Coord s, f, t;

48 priority_queue<Coord, vector<Coord>, comp> que;

49 memset(Dict, 0x7f, sizeof(Dict));

50 Dict[start.x][start.y] = 0;

51 que.push(start);

52 while(!que.empty())

53 {

54 s = que.top();

55 que.pop();

56 queue<Coord> queList;

57 queList.push(s);

58 while(!queList.empty())

59 {

60 f = queList.front();

61 queList.pop();

62 for(i = 0; i < 4; ++i)

63 {

64 t.x = f.x + DX[i];

65 t.y = f.y + DY[i];

66 if(isValid(t) && Dict[t.x][t.y] == INF)

67 {

68 if(Map[t.x][t.y] == Map[f.x][f.y])

69 {

70 Dict[t.x][t.y] = Dict[f.x][f.y];

71 queList.push(t);

72 }

73 else

74 {

75 Dict[t.x][t.y] = Dict[f.x][f.y] + 1;

76 que.push(t);

77 }

78 }

79 }

80 }

81

82 }

83 return Dict[end.x][end.y];

84 }

85 int main()

86 {

87 freopen("in.txt", "r", stdin);

88 int i;

89 Coord start, end;

90 while(scanf("%d%d", &N, &M) == 2)

91 {

92 for(i = 0; i < N; ++i)

93 scanf("%s", Map[i]);

94 scanf("%d%d%d%d", &start.x, &start.y, &end.x, &end.y);

95 printf("%d\n", solve(start, end));

96 }

97 return 0;

98 }

你可能感兴趣的:(中大省赛试机题【环形最大连续和】)