杭电ACM 1003 题 Max Sum

code_zhang 2009-07-02 02:08:49
Max Sum
Problem Description
Given a sequence a[1],a[2],a[3]......a[n], your job is to calculate the max sum of a sub-sequence. For example, given (6,-1,5,4,-7), the max sum in this sequence is 6 + (-1) + 5 + 4 = 14.



Input
The first line of the input contains an integer T(1<=T<=20) which means the number of test cases. Then T lines follow, each line starts with a number N(1<=N<=100000), then N integers followed(all the integers are between -1000 and 1000).



Output
For each test case, you should output two lines. The first line is "Case #:", # means the number of the test case. The second line contains three integers, the Max Sum in the sequence, the start position of the sub-sequence, the end position of the sub-sequence. If there are more than one result, output the first one. Output a blank line between two cases.



Sample Input
2
5 6 -1 5 4 -7
7 0 6 -1 1 -6 7 -5


Sample Output
Case 1:
14 1 4

Case 2:
7 1 6

以上是题目:
我测试了一下我的代码 完全能得到想要的结果 但是杭电那就是一直通不过 显示wrong 希望哪位高手帮我看一下是格式有问题还是特殊情况没有考虑进来


以下是我的代码:

#include<stdio.h>
int main()
{
int n,i,j,k=0,K,sum=0,SUM=0,end=0,start=1,flag=0,T=0,J;
int a[100000];
while((scanf("%d",&n))!=EOF)
{k=0;end=0;start=1;
while(n--)
{ SUM=0;end=0;start=1;
scanf("%d",&a[0]);
for(i=1;i<=a[0];i++)
{
scanf("%d",&a[i]);
}
for(i=1;i<=a[0];i++)
{
K=a[i];sum=0;
if(K>=0) end++;
if(a[i]<0)
{
int t=0;
sum=a[i];
for(j=i+1;sum<=0&&j<=a[0];j++)
{
sum=sum+a[j];t++;
}
if(sum<=0) {sum=0;K=0;flag=-t-1;}
i=j-1;
K=0;
end=i+flag;
flag=0;
}
SUM=SUM+sum+K;
}
T=0;
for(J=a[0];J>=0;J--)
{
if(a[J]==0) T++;
else break;
}
if(T==a[0]-J) end=end-T;
k++;
printf("Case %d:\n",k);
if(a[1]==0&&SUM==0) {end=1;start=1;}
if(SUM==0&&sum==0) {end=0;start=0;}
printf("%d %d %d\n\n",SUM,start,end);
}
}
return 0;
}
...全文
1960 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
sunzerui 2011-02-12
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 yuemengjie 的回复:]
为什么最大值的初值要设为-2147483640啊?我设成0或者-1的时候提交上去都是wrong,设成 -2147483640就对了,这是为什么啊?
[/Quote]
应该是设一个极小的数,容易判断;否则,容易出现错误。
设置成-1或0的话,如果输入一堆负数,不好和初值比较。
个人见解,望指正!
度假记忆 2010-11-29
  • 打赏
  • 举报
回复
dfgfdsgfd
YUEMENGJIE 2010-08-04
  • 打赏
  • 举报
回复
为什么最大值的初值要设为-2147483640啊?我设成0或者-1的时候提交上去都是wrong,设成 -2147483640就对了,这是为什么啊?
code_zhang 2009-07-03
  • 打赏
  • 举报
回复
回复楼上的:谢谢指教 以前没接触过DP 现在初步接触了一下 感觉以前的那些静态的算法分析都多多少少有那么一些固定的公式可循 但动态规划 要比这个复杂多了,自己到百度上找了点资料 看了好几遍 硬是没看懂 后来问了自己QQ好友里面的一个ACM牛人 他把以前做这道题的代码给我看了一下 是用C++的 具体核心思想跟楼上的差不多。我把它给成我自己的C的方式,其中出现了很多的问题,但还是一一给解决了,还挺小有成就感的。暑假也想好好训练一下自己,再次感谢tanader!下次我有不懂的地方 还请多多指教。
#include<stdio.h>
int main()
{
int t,j;
scanf("%d",&t);
for(j=0;j<t;j++){
int a[100000];
int start=0,end=0,SUM=-0x7fffffff,sum=-0x7fffffff,n,s=-1,i;
scanf("%d",&n);
for(i=0;i<n;i++){
scanf("%d",&a[i]);
if(sum>=0) sum+=a[i];
else if(sum<a[i]){
s=i;
sum=a[i];

}
if(sum>SUM){
SUM=sum;
start=s;
end=i;
}
}
printf("Case %d:\n",j+1);
printf("%d %d %d\n",SUM,start+1,end+1);
if(j!=t-1) printf("\n");
}
return 0;
}
tanadar 2009-07-02
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 code_zhang 的回复:]
引用 5 楼 tanadar 的回复:
代码写的真烂,哪有你这样写DP的。


恩 谢谢你批评 对于DP确实没怎么了解过 待会就是找点资料来把DP算法学习一下 然后把我的代码(我也觉得逻辑上有点乱,像是缝缝补补一样的)再重新编一下 总之 非常感谢各位
[/Quote]不错,虚心的孩子一定会有收获的。。。
code_zhang 2009-07-02
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 liao05050075 的回复:]
输入
1
2 -1 1

结果应该是1 2 2

但你的结果是0 0 0
[/Quote]

额 你比我细心多了 谢了
code_zhang 2009-07-02
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 baihacker 的回复:]
C/C++ code
//下面的代码能够AC这个问题
Problem : 1003 ( Max Sum ) Judge Status : Accepted
RunId : Language : G++ Author :

#include <iostream>
using namespace std;

int max_sum(int* data, int n, int& s, int& e)
{
int ans = -2147483640, curr = 0;
int start = 0, end = 0;
for (int i = 0, j = 0; i < n; ++i)
{
curr += data[i];
if (curr > ans) …
[/Quote]

谢了 虽然还不知道G++是什么 留着我待会看完DP算法在来研究
code_zhang 2009-07-02
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 tanadar 的回复:]
代码写的真烂,哪有你这样写DP的。
[/Quote]

恩 谢谢你批评 对于DP确实没怎么了解过 待会就是找点资料来把DP算法学习一下 然后把我的代码(我也觉得逻辑上有点乱,像是缝缝补补一样的)再重新编一下 总之 非常感谢各位
liao05050075 2009-07-02
  • 打赏
  • 举报
回复
输入
1
2 -1 1

结果应该是1 2 2

但你的结果是0 0 0
tanadar 2009-07-02
  • 打赏
  • 举报
回复
google一下一堆,关键是楼主那个代码写的不好,不想仔细看了。
baihacker 2009-07-02
  • 打赏
  • 举报
回复

//下面的代码能够AC这个问题
Problem : 1003 ( Max Sum ) Judge Status : Accepted
RunId : Language : G++ Author :

#include <iostream>
using namespace std;

int max_sum(int* data, int n, int& s, int& e)
{
int ans = -2147483640, curr = 0;
int start = 0, end = 0;
for (int i = 0, j = 0; i < n; ++i)
{
curr += data[i];
if (curr > ans) ans = curr, s = j, e = i;
if (curr < 0) curr = 0, j = i + 1;
}
return ans;
}

int data[100005];
int main()
{
int cas;scanf("%d", &cas);
for (int curr = 1; curr <= cas; ++curr)
{
if (curr > 1) puts("");
int n, s, e;scanf("%d", &n);
for (int i = 0; i < n; ++i)scanf("%d", data+i);
printf("Case %d:\n%d", curr, max_sum(data, n, s, e));
printf(" %d %d\n", s+1, e+1);
}
return 0;
}
tanadar 2009-07-02
  • 打赏
  • 举报
回复
代码写的真烂,哪有你这样写DP的。
code_zhang 2009-07-02
  • 打赏
  • 举报
回复
#include<stdio.h>
int main()
{
int n,i,j,k=0,K,sum=0,SUM=0,end=0,start=1,flag=0;
int a[100000];
if((scanf("%d",&n))!=EOF)
{
while(n--)
{ SUM=0;end=0;start=1;
scanf("%d",&a[0]);
for(i=1;i<=a[0];i++)
{
scanf("%d",&a[i]);
}
for(i=1;i<=a[0];i++)
{
K=a[i];sum=0;
if(K>=0) end++;
if(a[i]<=0)
{
int t=0;
sum=a[i];
for(j=i+1;sum<=0&&j<=a[0];j++)
{
sum=sum+a[j];t++;
}
if(sum<=0) {sum=0;K=0;flag=-t-1;}
i=j-1;
K=0;
end=i+flag;
flag=0;
}
SUM=SUM+sum+K;
}
k++;
printf("Case %d:\n",k);
if(a[1]==0&&SUM==0) {end=1;start=1;}
if(SUM==0&&sum==0) {end=0;start=0;}
printf("%d %d %d\n\n",SUM,start,end);
}
}
return 0;
}


综合楼上的我又改了一下我的代码 运行了一下 感觉能考虑的都考虑进来了 结果也都没什么问题 但是在杭电那编译还是提示wrong

运行结果:
10
5 6 -1 5 4 -7
Case 1:
14 1 4

7 0 6 -1 1 -6 7 -5
Case 2:
7 1 6

6 0 0 -8 4 5 0
Case 3:
1 1 5

6 0 0 -8 4 2 2
Case 4:
0 0 0

6 -8 0 0 0 0 0
Case 5:
0 0 0

6 -8 0 0 0 0 5
Case 6:
0 0 0

6 8 0 0 0 0 -8
Case 7:
8 1 1

1 0
Case 8:
0 0 0

8 0 0 0 0 0 0 0 0
Case 9:
0 0 0

10 -8 -2 -3 -4 4 5 9 8 0 5
Case 10:
14 1 10

Press any key to continue
expter 2009-07-02
  • 打赏
  • 举报
回复
DP算法啊。。。
logiciel 2009-07-02
  • 打赏
  • 举报
回复
另外,是否需要改为从文件输入?是否需要检查输入数据符合题目要求的范围?
logiciel 2009-07-02
  • 打赏
  • 举报
回复
以下第一行错了:
while((scanf("%d",&n))!=EOF)
{k=0;end=0;start=1;

应改为:
if((scanf("%d",&n))!=EOF)

这是因为第一行输入数据代表case总数,只出现一次,不需要循环。
tanadar 2009-07-02
  • 打赏
  • 举报
回复
DP关键是列出状态转移方程,下面是一段分析,和相应的伪代码:

/*
设 f[i] 是 1 - i 的,包含 i 的,最大序列的和,那么:
f[1] = a[1];
f[i+1] = f[i] > 0 ? f[i] + a[i+1] : a[i+1]
继而,最大子序列和就是 f[1] .. f[n] 中最大的那一个。
*/

main()
{
// do something here
// ...
for (i = 1; i < n; i++)
{
if (max > 0)
{
max += a[i];
}
else
{
max = a[i];
start = i;
}

if (resMax < max)
{
resMax = max;
resStart = start;
resEnd = i;
}
}
// do something here
// ...
}

ACM很辛苦,努力把。

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧