ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2022-04-09 09:35:10  阅读:171  来源: 互联网

标签:洛谷 int max d% 露诺 DP ans inf dp


显然的DP题.....

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

第一种: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[i−r],...,dp[i−l])就是找这个区间中的最大值,类似于滑动窗口的思想,建立一个单减的队列。

 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方程,观察式子看能不能使用数据结构来优化,可能优化方式不止一种。

标签:洛谷,int,max,d%,露诺,DP,ans,inf,dp
来源: https://www.cnblogs.com/yhxnoerror/p/16120862.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有