之前不太理解,只记得和为负的就记为0,然后不断扫下去,更新ans
实际上用了 sum[i]-sum[j] ,令ans最小,即找出最大的sun[j](j<i)
hdu1003 还要求出起始点和终点
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
using namespace std;
int dp[100500],n;
int main ()
{
dp[0]=0;
int test;scanf("%d",&test);
for(int k=1;k<=test;++k)
{
scanf("%d",&n);
bool flag=true;
for(int i=1;i<=n;++i)
{
scanf("%d",&dp[i]);
if(dp[i]>0)
flag=false;
}
int ans=-1000000000,st,ed;
if(flag) // 所有都是负的,特判
{
for(int i=1;i<=n;++i)
if(ans<dp[i])
ans=dp[i],st=ed=i;
}
else
{
int sum=0;st=ed=1;
for(int i=1,j=1;i<=n;++i)
{
sum+=dp[i];
if(sum>ans)
{
st=j;
ed=i;
ans=sum;
}
if(sum<0)
{
sum=0;
j=i+1;
}
}
}
printf("Case %d:\n",k);
printf("%d %d %d\n",ans,st,ed);
if(k<test)
printf("\n");
}
//system("pause");
return 0;
}
poj1050 变形:化二维转化为一维问题
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
using namespace std;
#define N 105
int a[N][N];
int b[N],n;
int main ()
{
while(scanf("%d",&n)!=EOF)
{
bool flag=true;
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
{
scanf("%d",&a[i][j]);
if(a[i][j]>0)
flag=false;
}
int ans=-10000000,sum;
if(flag)
{
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
if(ans<a[i][j])
ans=a[i][j];
printf("%d\n",ans);
continue;
}
for(int up=1;up<=n;++up)
{
memset(b,0,sizeof(b));
for(int down=up;down<=n;++down)
{
for(int j=1;j<=n;++j)
b[j]+=a[down][j];
sum=0;
for(int j=1;j<=n;++j)// 利用一维连续子序列和o(n)时间求出
{
sum+=b[j];
if(sum<0)
sum=0;
if(sum>ans)
ans=sum;
}
}
}
printf("%d\n",ans);
}
//system("pause");
return 0;
}
soj 1800 变形:有限制长度的连续子段和
网上都是用线段树做的,完全没必要= = ,优先队列更快更简洁
开始先暂存在一个队列中,能使长度满足下限push进优先队列,长度大于上限obj 出优先队列
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
int n,l,r;
struct obj
{
int s,index;
obj(int _s,int _index)
{
s=_s;index=_index;
}
obj()
{
s=index=0;
}
bool operator<(const obj& right) const
{
return s<right.s;
}
};
priority_queue<obj>q;
queue<obj>tt;
int main ()
{
while(scanf("%d",&n)!=EOF&&n)
{
scanf("%d%d",&l,&r);
while(!q.empty())
q.pop();
while(!tt.empty())
tt.pop();
int sum=0,ans=0,u;
obj temp;
tt.push(obj(0,0));
for(int i=1;i<=n;++i)
{
scanf("%d",&u);
sum+=u;
tt.push(obj(sum,i));
if(i<=l)
{
ans+=u;
continue;
}
temp=tt.front();
while(!tt.empty()&&i-temp.index>=l)
{
tt.pop();
q.push(temp);
temp=tt.front();
}
temp=q.top();bool flag=false;
while(i-temp.index>r)
{
q.pop();
if(q.empty())
{
flag=true;
break;
}
temp=q.top();
}
if(!flag&&ans>sum-temp.s)
ans=sum-temp.s;
}
printf("%d\n",ans);
}
//system("pause");
return 0;
}