标签:
Input
Output
Sample Input
Sample Output
大致题意:
给一个序列,找出他的和最大的子序列;
解题思路:
以下有两个代码:
第一个代码:
贪心,遍历所有可能,找最大,当然会超时,所以要剪枝;复杂度O(n^2);
第二个代码:
比较神奇,DP,复杂度0(n);
以a[0]结尾的子序列只有a[0]
以a[1]结尾的子序列有 a[0]a[1]和a[1]
以a[2]结尾的子序列有 a[0]a[1]a[2] / a[1]a[2] / a[2]
很容易得出状态转移方程式 sum_a[i]=max(sum_a[i-1]+a[i],a[i]);
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 int main() 5 { 6 int t,n,a[100005]; 7 cin>>t; 8 for(int k=1;k<=t;k++) 9 { 10 cin>>n; 11 for(int i=1;i<=n;i++) 12 cin>>a[i]; 13 int max,ans=-99999999,a1,a2; 14 for(int i=1;i<=n;i++) 15 { 16 max=0; 17 for(int j=i;j<=n;j++) 18 { 19 max+=a[j]; 20 if(max>ans) 21 { 22 ans=max; 23 a1=i; 24 a2=j; 25 } 26 if(max<0) break; 27 } 28 } 29 printf("Case %d:\n",k); 30 printf("%d %d %d\n",ans,a1,a2); 31 if(k<t) cout<<endl; 32 } 33 }
1 #include <cstdio> 2 int main(){ 3 int t,cas=0; 4 scanf("%d",&t); 5 while(t--&&++cas) 6 { 7 if(cas!=1) printf("\n"); 8 printf("Case %d:\n",cas); 9 int a[100001],f[100001]={0}; 10 int max,maxl,maxr,l,r,n; 11 scanf("%d",&n); 12 l=1; max=-100000; 13 for(int i=1;i<=n;i++){ 14 scanf("%d",&a[i]); 15 if(f[i-1]+a[i]<a[i]) { f[i]=a[i]; l=i; r=i; } 16 else{ f[i]=f[i-1]+a[i]; r=i; } 17 if(max<f[i]){ max=f[i]; maxl=l; maxr=r; } 18 } printf("%d %d %d\n",max,maxl,maxr); 19 } return 0; 20 }
标签:
原文地址:http://www.cnblogs.com/nicetomeetu/p/5159183.html