Codeforces Round #613 (Div. 2) B. Just Eat It! (DP)
-
题意:有一个长度为\(n\)的序列,找出最大的长度不为\(n\)的子段和,问最大子段和是否小于所有元素和.
-
题解:最大子段和我们可以直接用dp来找,每次状态转移为:\(dp[i]=max(dp[i-1]+a[i],a[i])\),而我们不能求长度为\(n\)的子段和,所以可以跑两次,从\([1,n-1]\)和\([2,n]\)维护一个最大值即可.
-
代码:
int t; int n; ll a[N]; ll dp[N]; ll sum; int main() { //ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); scanf("%d",&t); while(t--){ sum=0; scanf("%d",&n); for(int i=1;i<=n;++i){ scanf("%lld",&a[i]); sum+=a[i]; } ll mx=-INF; for(int i=1;i<n;++i){ dp[i]=max(dp[i-1]+a[i],a[i]); mx=max(mx,dp[i]); } for(int i=1;i<=n;++i) dp[i]=0; for(int i=2;i<=n;++i){ dp[i]=max(dp[i-1]+a[i],a[i]); mx=max(mx,dp[i]); } if(mx>=sum) puts("NO"); else puts("YES"); for(int i=1;i<=n;++i) dp[i]=0; } return 0; }
𝓐𝓬𝓱𝓲𝓮𝓿𝓮𝓶𝓮𝓷𝓽 𝓹𝓻𝓸𝓿𝓲𝓭𝓮𝓼 𝓽𝓱𝓮 𝓸𝓷𝓵𝔂 𝓻𝓮𝓪𝓵
𝓹𝓵𝓮𝓪𝓼𝓾𝓻𝓮 𝓲𝓷 𝓵𝓲𝓯𝓮