1 solutions
-
-2
暴力过不了大数据,所以要用双端队列来降低时间复杂度 双端队列优点:可以在滑动窗口内刷新最大值,从而将时间复杂度降为O(n)
#include<iostream> #include<deque> #include<climits> using namespace std; const int N=2e5+10; int a[N],dp[N],n,l,r,minn=INT_MIN; deque<int>ice; int main(){ cin>>n>>l>>r; for(int i=0;i<=n;i++){ cin>>a[i]; } fill(dp,dp+n+1,INT_MIN);//初始化dp数组 dp[0]=0; for(int j=0;j<=n;j++){ while(!ice.empty()&&ice.front()<j-r){ ice.pop_front();//批量清理过期元素(不能跳到当前格子的元素),若用if只能清理一个过期元素 //由于队列头部的元素必定更早加入队列,所以不用考虑除头部之外的过期元素 } if(j>=l){ while(!ice.empty()&&dp[ice.back()]<=dp[j-l]){ ice.pop_back();//若尾部元素小于想要新加入的元素,则弹出当前尾部元素以保持单调递减 } ice.push_back(j-l);//插入新加入的元素 } if(!ice.empty()){ dp[j]=dp[ice.front()]+a[j];//获取当前格子最大冰冻指数 } } for(int i=max(0,n-r+1);i<=n;i++){//防止n+1<r if(dp[i]>minn){ minn=dp[i];//求最大冰冻指数 } } cout<<minn;//脑子进水的我用了个minn(应该用maxn/(ㄒoㄒ)/~~) return 0; }
//压行版 #include<bits/stdc++.h> using namespace std; const int N=2e5+5; int a[N],dp[N],n,l,r,minn=INT_MIN; deque<int>ice; int main(){ cin>>n>>l>>r; for(int i=0;i<=n;i++)cin>>a[i]; fill(dp,dp+n+1,INT_MIN); dp[0]=0; for(int j=0;j<=n;j++){ while(!ice.empty()&&ice.front()<j-r)ice.pop_front(); if(j>=l){ while(!ice.empty()&&dp[ice.back()]<=dp[j-l])ice.pop_back(); ice.push_back(j-l); } if(!ice.empty())dp[j]=dp[ice.front()]+a[j]; } for(int i=max(0,n-r+1);i<=n;i++)if(dp[i]>minn)minn=dp[i]; cout<<minn; return 0; }
- 1
Information
- ID
- 703
- Time
- 1000ms
- Memory
- 125MiB
- Difficulty
- 4
- Tags
- # Submissions
- 97
- Accepted
- 12
- Uploaded By