洛谷P1725 琪露诺 (单调队列/堆优化DP)

显然的DP题.....

对于位置i,它由i-r~i-l的位置转移过来,容易得到方程 dp[i]=dp[i]+max(dp[ir],...,dp[il])。

第一种:n2的暴力,只能拿部分分。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=2e5+5,inf=0x3f3f3f3f;
 4 int n,l,r,a[N],dp[N],ans=-inf;
 5 
 6 int main(){
 7     scanf("%d%d%d",&n,&l,&r);
 8     for(int i=0;i<=n;i++) scanf("%d",&a[i]);
 9     memset(dp,-0x3f,sizeof(dp));
10     dp[0]=0;
11     for(int i=l;i<=n+r;i++){
12         for(int j=max(i-r,0);j<=i-l;j++){
13             dp[i]=max(dp[i],dp[j]+a[i]);
14         }
15         if(i>n) ans=max(ans,dp[i]);
16     }
17     cout<<ans;
18 }

注意细节:i从l到n+r枚举,i-r可能为负导致越界,所以取max(i-r,0);

第二种:单调队列优化,max(dp[ir],...,dp[il])就是找这个区间中的最大值,类似于滑动窗口的思想,建立一个单减的队列。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=2e5+5;
 4 int dp[N],q[N],a[N],n,l,r,ans=-0x3f3f3f3f;
 5 
 6 int main(){
 7     scanf("%d%d%d",&n,&l,&r);
 8     for(int i=0;i<=n;i++) scanf("%d",&a[i]);
 9     memset(dp,-0x3f,sizeof(dp));
10     dp[0]=0;
11     int h=1,t=0;
12     for(int i=l;i<=n;i++){
13         while(h<=t && dp[q[t]]<=dp[i-l]) t--;
14         q[++t]=i-l;
15         while(h<=t && q[h]<i-r) h++;
16         dp[i]=dp[q[h]]+a[i];
17     }
18     for(int i=n-r+1;i<=n;i++)
19         ans=max(ans,dp[i]);
20     cout<<ans<<endl;
21 }

第三种:堆优化(大根堆),思想和上一种差不多,都是维护区间最大值,(个人感觉堆优化的代码要简单一小小小些)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=2e5+5,inf=0x3f3f3f3f;
 4 int n,l,r,dp[N],a[N],ans=-inf;
 5 struct node{
 6     int p,val;
 7     friend bool operator < (node a,node b){
 8         return a.val<b.val;//大根堆 
 9     }
10 };
11 priority_queue<node> q;
12 int main(){
13     scanf("%d%d%d",&n,&l,&r);
14     memset(dp,-0x3f,sizeof(dp));
15     for(int i=0;i<=n;i++) scanf("%d",&a[i]);
16     dp[0]=0;
17     for(int i=l;i<=n;i++){
18         q.push((node){i-l,dp[i-l]});
19         while(q.top().p<i-r) q.pop();
20         dp[i]=q.top().val+a[i];
21     }
22     for(int i=n-r+1;i<=n;i++)
23         ans=max(ans,dp[i]);
24     cout<<ans;
25 }

对于这种题,要写出DP方程,观察式子看能不能使用数据结构来优化,可能优化方式不止一种。

posted @ 2022-04-09 09:15  YHXo  阅读(26)  评论(0编辑  收藏  举报