主题:43-2结果
thomas [专家分:180] 发布于 2006-10-03 17:31:00
NAME CASE1 CASE2 CASE3 CASE4 CASE5
flypampas 0MS 0MS WRONG ANS TIME LIMIT OUT
bood 0ms 0ms 20ms 70ms 170MS
senzheng与bood答案一样,但是很遗憾晚交了.由于答题人少,虽然此题技术含量甚高,但缺乏可比性,只好颁发给bood一个鼓励奖,实在是对不起你了
这道题的标准做法是用一个堆,设S[I]为前I项之和,要找到M个数和最大,就是要S[RIGHT]-S[LEFT]最大,可扫描S[RIGHT],只需找到一个LEFT,使S[LEFT]最小且L1<RIGHT-LEFT<L2,用个堆维护就行了
回复列表 (共12个回复)
沙发
senzhang [专家分:160] 发布于 2006-10-03 18:52:00
能不能问下,编程比赛是怎么回事啊?我还以为什么时候都可以交呢
板凳
thomas [专家分:180] 发布于 2006-10-03 20:10:00
在关于比赛的帖子里有比赛时间要求
3 楼
bood [专家分:490] 发布于 2006-10-03 21:42:00
标准解法没听懂?能具体解释下么?
不知道thomas能否告知标程在这几个case的耗时啊?:)
p.s. 也可以帮senzeng试试嘛,或者直接给出测试数据让他自己测
4 楼
thomas [专家分:180] 发布于 2006-10-03 21:53:00
这里最大的数据也只有20000.而原题有300000
标准做法用堆,O(NLOGN),还有一种做法用队列,O(N)的复杂度,过300000的数据也只要100MS
5 楼
boxertony [专家分:23030] 发布于 2006-10-03 22:48:00
楼主能否给出用队列实现的代码?
6 楼
neverPE [专家分:1620] 发布于 2006-10-04 03:01:00
这是标准的最大子段和,DP是典型解法,O(n)
a[]为序列,b[]保存前若干项的最大字段和。状态转移方程b[j] = max{ b[j-1] + a[j] , a[j] } , 1 <= j <= n。
任意一本介绍DP的书,这道题都是典型例题。google也很容易找到代码
PS:这次的2道题都很容易找到解题报告,不知道是否因为这个原因导致人气不高。太典型的OI/ACM题还是不要直接拿过来的好,至少应该稍微修改一下。我以前AC过的代码几乎可以直接贴过来,所以实在没兴趣参加。
7 楼
thomas [专家分:180] 发布于 2006-10-04 09:24:00
对子段的长度无限制,当然简单,但是对子段的长度有限制就不一样了
PS:现在找不到题解的题实在是太少了
8 楼
thomas [专家分:180] 发布于 2006-10-04 18:32:00
题解:
http://www.programfan.com/club/showbbs.asp?id=195598
9 楼
boxertony [专家分:23030] 发布于 2006-10-05 23:22:00
// 根据堆实现改编的队列实现
__int64 MaxSum(int a[], int n, int l1, int l2)
{
__int64 max;
__int64 temp;
__int64 *sum;
__int64 s;
int *queue;
int i;
int f, r;
max = -INT_MAX;
max *= INT_MAX;
sum = new __int64[n+1];
assert(sum != NULL);
queue = new int[n+1];
assert(queue != NULL);
s = 0;
f = 1;
r = 0;
sum[0] = 0;
for(i=1; i<=n; ++i)
{
s += a[i-1];
sum[i] = s;
if(i < l1)
continue;
while(f<=r && i-queue[f]>l2)
++f;
while(f<=r && sum[i-l1]<=sum[queue[r]])
--r;
++r;
queue[r] = i - l1;
temp = s - sum[queue[f]];
if(temp > max)
max = temp;
}
delete []sum;
delete []queue;
return max;
}
10 楼
stormxiao [专家分:30] 发布于 2006-10-05 23:50:00
能不能发下测试代码啊?
我来回复