3 solutions
-
1
首先想到应该是时间复杂度为O()的暴力枚举。读入a[],b[]两个数组,然后依次枚举每个位,让b[i]的取值为0并且把b[i]中的数据存储下来,从1开始枚举得到w的自小值,最后的答案是a[0]减去w的最小值。
#include<iostream> using namespace std; const int N=1e5+10; int a[N],b[N]; int main(){ int n;cin>>n; for(int i=0;i<=n;i++){ cin>>a[i]; } for(int i=1;i<=n;i++){ cin>>b[i]; } for(int i=1;i<=n;i++){ int x=b[i];b[i]=0; int w=0,ans=1e9; for(int j=1;j<=n;j++){ w=w+b[j]; w=w-a[j]; ans=min(w,ans); } cout<<a[0]-ans<<" "; b[i]=x; } return 0; }暴力枚举只能过百分之八十的数据,接下来需要进行公式推导。w+>=,那w应该取 -的最大值,这里维护一个数组c[]来依次存储前面我们所说的差值。将b[i]的值赋为0并不影响前半部分的c[i],但是后半部分的c[i]需要再加一个b[i]。所以在这里维护一个数组pre[]存储前i个数中c[i]的最值,再维护一个数组suf[]存储后i个数的最值。最后答案的取值就是max(pre[i],suf[i]+b[i])。
#include<iostream>//前缀和 using namespace std; const int N=1e5+10; int a[N],b[N],ans[N]; int c[N],pre[N],suf[N]; int main(){ int n;cin>>n; for(int i=1;i<=n+1;i++)cin>>a[i]; for(int i=1;i<=n;i++)cin>>b[i]; pre[0]=suf[n+2]=-1e9; for(int i=1;i<=n+1;i++){//需要自己进行公式推导 c[i]=c[i-1]+a[i]-b[i-1];//c[i]是对a[i]求和-b[i]的最大值 pre[i]=max(pre[i-1],c[i]); } for(int i=n+1;i;--i)suf[i]=max(suf[i+1],c[i]);//后缀的最大值 for(int i=1;i<=n;i++){ ans[i]=max(pre[i],suf[i+1]+b[i]);//前缀不影响,后缀加上b[i]即可 cout<<max(ans[i],0)<<" "; } return 0; }
Information
- ID
- 41
- Time
- 1000ms
- Memory
- 512MiB
- Difficulty
- 2
- Tags
- # Submissions
- 232
- Accepted
- 54
- Uploaded By