题意:首先输入N,表示接下来N组数据,再输入M,表示每组数据有M-1个数字,求数字最大子序和,而且打印出其起点和终点.
思路:动态规划,最大子序和
该题和 UVA, 10684 The jackpot 相似,只是多加了一个查找起点终点操作和输入数字的变化。
代码如下:
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 using namespace std; 6 7 int n,m,date[20005],f[20005];//数组大小要够,不然WA 8 int st[20005],be,fi;//(╯‵□′)╯︵┻━┻我一开始就WA了 9 10 11 void showf() 12 { 13 cout<<"f:"; 14 for(int i=0;i<m;i++) 15 cout<<f[i]<<' '; 16 cout<<endl; 17 } 18 void showst() 19 { 20 cout<<"st:"; 21 for(int i=0;i<m;i++) 22 cout<<st[i]<<' '; 23 cout<<endl; 24 } 25 //showf 和showst函数是我用来查看f和st数组中元素 26 27 int findm(int l)//用于查找起点 28 { 29 int be;//= =这里一开始忘加了,弄得被修改了好多次,找了半天 30 for(int i=l;i>0;i--) 31 { 32 if(st[i]<0) 33 break; 34 be=i; 35 } 36 return be; 37 } 38 void datecal(int k) 39 { 40 memset(f,0,sizeof(f)); 41 f[0]=date[0]; 42 int maxn=0; 43 for(int i=1;i<=m;i++) 44 { 45 if(f[i-1]>=0) 46 { 47 st[i-1]=i-1; 48 f[i]=f[i-1]+date[i]; 49 } 50 else 51 { 52 f[i]=date[i]; 53 st[i-1]=-1; 54 } 55 } 56 //showf();showst(); 57 for(int i=0;i<=m;i++) 58 { 59 if(maxn<f[i]) 60 { 61 maxn=f[i]; 62 fi=i; 63 } 64 } 65 66 if(maxn!=0) 67 { 68 be=findm(fi); 69 //cout<<fi<<':'<<be<<endl; 70 for(int i=0;i<=m;i++) 71 { 72 if(maxn==f[i]&&i!=fi)//进行长度比较 73 { 74 int temp=fi+1-be; 75 int fil=i; 76 int bel=findm(i); 77 int temq=fil-bel; 78 if(i!=m)temq++; 79 if(temq>temp) 80 { 81 fi=fil; 82 be=bel; 83 } 84 } 85 } 86 if(fi!=m)fi++; 87 printf("The nicest part of route %d is between stops %d and %d ",k,be,fi); 88 } 89 else 90 printf("Route %d has no nice parts ",k); 91 } 92 93 94 int main() 95 { 96 scanf("%d",&n); 97 int k=1; 98 for(int i=0;i<n;i++) 99 { 100 scanf("%d",&m); 101 memset(date,0,sizeof(date)); 102 date[0]=0; 103 for(int j=1;j<m;j++) 104 { 105 scanf("%d",&date[j]); 106 //cout<<date[j]<<endl; 107 } 108 datecal(k); 109 k++; 110 111 } 112 return 0; 113 }
该题需注意同一大小的子序和,选择长度较大的