之前不太理解,只记得和为负的就记为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; }