中大省赛试机题【环形最大连续和】
题意:给一连串的数字, 组成一个环,找出其最大的连续和.
解题思路:
如果不是环,直接用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 }
浙公网安备 33010602011771号