输入样例 1:
5 997
1 2 3 4 5
输出样例 1:
21
输入样例 2:
5 7
-1 -1 -1 -1 -1
输出样例 2:
-1
第一次写代码的时候,我的代码是这样的
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e6+10;
long long n,a[N],mod;
long long dp[N],ans=-0x3f3f3f3f,res=0;
int main(void)
{
scanf("%lld%lld",&n,&mod);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
if(res<0) res=0;
res=res+a[i];
ans=max(res,ans);
dp[i]=ans;
}
a[1]=dp[1];
ans=a[1]+a[1];
long long mn=a[1];
for(int i=2;i<=n;i++)
{
a[i]=ans;
ans=max(ans,dp[i]+a[i]);
mn=max(mn,a[i]);
}
cout<<mn%mod;
}
很明显,最后一步很致命,我知道最后一步不仅要考虑带模运算问题,还要考虑正负数问题,不过可以知道的是最后一个一定是最大的,这个毫无疑问,但是我们无法确定负数情况下,第一个和最后一个谁大,因为这是第2-n中逐渐递推的,1,2之间是没有比较的,所以我们的代码改进版,也是AC版出来了。
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
const int N=1e6+10;
LL a[N],dp[N];
LL n,mod,res=0,ans=-0x3f3f3f3f;
int main(void)
{
scanf("%lld%lld",&n,&mod);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
if(res<0) res=0;
res+=a[i];
ans=max(ans,res);
dp[i]=ans;
}
a[1]=dp[1];
a[2]=(dp[1]+dp[1])%mod;
for(int i=3;i<=n;i++)
{
a[i]=max(a[i-1],a[i-1]+dp[i-1]);
a[i]%=mod;
}
if(a[1]>0) res=a[n];//这一步疑问比较大一点
else res=max(a[1],a[n]);
cout<<res%mod;
}