版权声明:转载请注明出处https://blog.csdn.net/hhmy77 https://blog.csdn.net/hhmy77/article/details/88898556
经典DP
这题要注意看题
1.如果输入的数字中都是负数,那么输出0和首位的值(0是非负的)
2.In case that the maximum subsequence is not unique, output the one with the smallest indices i and j (as shown by the sample case),这里我理解应该是碰到相同的情况输出字典序较小的边界
比如说
5
2 2 -4 1 3
这里应该输出1 3对吧?但是测试样例并没有这样要求。
正确解法
下面是正确的解法
#include<iostream>
#include<math.h>
using namespace std;
const int limt=10010;
int dp[limt]={0};
int A[limt]={};
void findL(int &L,int tmp,int index)
{
while(A[index-1]!=tmp-A[index])
{
tmp-=A[index--];
}
L=A[index-1];
}
int main()
{
//6
//-2 11 -4 13 -5 -2
bool z=false;
int n;
cin>>n;
int maxn=-limt;
int L=0,R=0;
for(int i=1;i<=n;i++)
{
cin>>A[i];
if(A[i]>=0)z=true;
}
if(!z)
{
cout<<0<<" "<<A[1]<<" "<<A[n];
return 0;
}
for(int i=1;i<=n;i++)
{
dp[i]=max(A[i],dp[i-1]+A[i]);
//如果出现了最大值
if(dp[i]>=maxn)
{
//如果等于 更改LR为较小值
//但是测试样例并没有这样要求 所以可以注释掉,上面if条件改为(dp[i]>maxn)
if(dp[i]==maxn)
{
int tR=A[i];
int tL=0;
findL(tL,dp[i],i);
if(tL<L)
{
L=tL,R=tR;
}
}
else
{
maxn=dp[i];
//如果是单个最大
if(dp[i]==A[i])
{
L=A[i];
R=A[i];
}
else
{
//区间最大 更新区间
R=A[i];
findL(L,dp[i],i);
}
}
}
}
cout<<maxn<<" "<<L<<" "<<R;
return 0;
}
暴力 没有AC
#include<iostream>
using namespace std;
const int maxn=10010;
int dp[maxn][maxn]={};
int main()
{
bool z=false;
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>dp[0][i];
if(dp[0][i]>0)z=true;
}
if(!z)
{
cout<<0<<" "<<dp[0][1]<<" "<<dp[0][n];
return 0;
}
for(int i=1;i<=n;i++)
{
dp[i][i]=dp[0][i];
}
int max=0;
int L=0,R=0;
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
dp[i][j]=dp[i][j-1]+dp[0][j];
if(dp[i][j]>max)
{
max=dp[i][j];
L=dp[0][i];
R=dp[0][j];
}
}
}
cout<<max<<" "<<L<<" "<<R;
return 0;
}
提交情况,最后一个应该是超时了,还有两个case没通过