2 条题解

  • 0
    @ 2024-6-15 20:53:27

    此处列出核心代码 自己按需打包或添加循环

    for(int i=0;i<n;i++){
            cin >> a;
            nans=max((a),nans+(a));
            ans=max(nans,ans);
    }
    
    • 0
      @ 2024-6-11 20:12:32

      注意到 n2×105n\le 2\times10^5,用前缀和暴力枚举是不成了,我们可以用dp来做。

      f[i]f[i]a[1]a[i]a[1]\sim a[i] 的最大子段和,初始 f[1]=a[1]f[1]=a[1]。对于一个 ii,无非就是两种情况:

      f[i]={a[i],f[i1]0f[i1]+a[i],f[i1]>0f[i]=\begin{cases} a[i],\,f[i-1]\le0\\ f[i-1]+a[i],\,f[i-1]>0 \end{cases}

      f[i1]0f[i-1]\le0 时,无论如何 f[i1]f[i-1] 都不可能比 a[i]a[i] 大,所以我们就开始一段新的区间;否则当 f[i1]>0f[i-1]>0 时,我们令其加上 a[i]a[i] 以开始新的转移。

      与LIS一样,答案并不一定就是 f[n]f[n],而是 max1inf[i]\max_{1\le i\le n}f[i]

      #include<bits/stdc++.h>
      using namespace std;
      const int N=2e5+5,INF=0x3f3f3f3f;
      int n,f[N],ans=-INF;
      int main(){
      	scanf("%d",&n);
      	for(int i=1,x;i<=n;i++){
      		scanf("%d",&x);
      		if(i==1||f[i-1]<=0)
      			f[i]=x;
      		else
      			f[i]=f[i-1]+x;
      		ans=max(ans,f[i]);
      	}
      	printf("%d",ans);
      	return 0;
      }
      
      
      • 1

      信息

      ID
      797
      时间
      1000ms
      内存
      125MiB
      难度
      4
      标签
      递交数
      146
      已通过
      65
      上传者