昨天,啊不前天去学校收拾寝室最后一点行李,也算最后毕业啦,希望我的同学们前程似锦,永远不脱发!现在是凌晨1点58分,女神已经睡着了,而我因为刚醒不久开始写昨天的博客 1003题 此题让求序列中的最大和,并标明子序列的开始位置,子序列的结束位置,这道题在写的时候,容易忘记讨论究竟序列的开始位置究竟是哪里,一定不要想当然的根据题中给的数据就不考虑如果先输入负数这种情况,刚刚突然想到一种情况如果全输入负数呢?后来一想这种情况毫无意义上代码:
#include <stdio.h> int a[100010]; int main() { int T,N = 1; scanf("%d",&T); while(T--) { int i,t,x,y; int n=1,sum=0,max=-999; scanf("%d",&t); for(i=1; i<=t;i++) { scanf("%d",&a[i]); sum = sum + a[i]; if(sum>max) { max=sum; x=n; y=i; } if(sum<0) { sum=0; n=i+1; } } printf("Case %d:\n",N++); printf("%d %d %d\n",max,x,y); if(T) printf("\n"); } return 0; }1087题 本题实际是非连续递增序列求和,看到这题我们会想到,苹果放盘子的那个程序,我们不妨对比着来,之前那个程序我们设置了一个二维数组,前面代表苹果,后面代表盘子,整体二维数组代表摆放的情况,这道题我们需要什么呢?我们需要前一个数,后一个数以及他们之间的关系就OK了,既然是这样,我们用dp[i],dp[j],分别代表以i,j结尾的子串最大和,i作为大循环的循环变量,j作为小循环的循环变量,在每个不同i的前提下,之前数(j)比当前数(i)小,就将当前数与之前数相加,若之前数不比当前数小,直接就是当前数,再寻找最大和就OK啦! 代码如下:
#include<stdio.h> int max(int a, int b) { if(a>b) return a;return b; } int main() { int n; int num[1001],dp[1001]; int max_num; int i,j; while(scanf("%d",&n)!=EOF&&n) { max_num=-1; memset(dp,0,sizeof(dp)); for(i=1;i<=n;i++) scanf("%d",&num[i]); for(i=1;i<=n;i++) { for(j=0;j<=i;j++)//之前数比当前数小,就将当前数与之前数相加 if(num[i]>num[j]) dp[i]=max(dp[i],dp[j]+num[i]); dp[i]=max(dp[i],num[i]);//若之前数不比当前数小,直接就是当前数 max_num=max(max_num,dp[i]);//寻找最大和 } printf("%d\n",max_num); } return 0; }