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

题目: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 }
posted on 2011-05-07 20:50  Kenfly  阅读(353)  评论(0编辑  收藏  举报