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