2025/1/11课堂记录

目录

  1. 扫描
  2. 绿色通道

更详细的单调dp模板

#include <bits/stdc++.h>
using namespace std;
const int maxN=1000005;
int a[maxN],q[maxN];
//        q[]:  i <  j
//        f[i] <f[j]  or  f[i]>f[j] 
int main()
{
    int n,k;
    cin>>n>>k;
    for(int i=1;i<=n;i++)
	{
        cin>>a[i];
    }
    
    int h=0,t=0; 
	//head指向真正的队头,tail的前1位指向队尾(tail-1)
	//h<t  队列不为空 
    for(int i=1;i<=n;i++)
	{
		//保证i加入序列后,区间长度<=k 
        while(h<t&&q[h]+k<=i) // q[h]<=i-k   ,  q[h]=j
		{
            h++;
        }
        //队尾插入a[i],确保下降 ; t-1指向真正的队尾 
        while(h<t&&a[q[t-1]]<a[i])
		{
            t--;
        }
        q[t++]=i;//入队 
        if(i>=k)cout<<a[q[h]]<<endl;
    }
    return 0;
}

具体见2024/12/21

有个问题:题目给的读入n,t

但是单调队列还有个h,t

变量重名了,改了半天

补0:f[i]=min/max(g(j))+a[i]中的a[i]有东西时就要补

代码再放一次吧,反正不嫌多
 #include<iostream>
#include<cstring>
using namespace std;
int a[50010],q[50010],f[50010];
int n,t;
bool check(int mid)
{
	memset(q,0,sizeof(q));
	memset(f,0,sizeof(f));
	int l=0,r=1,ans=0x3f3f3f3f;
	for(int i=1;i<=n;i++)
	{
		while(l<r&&q[l]<i-mid-1)l++;
		f[i]=a[i]+f[q[l]];
//		if(i>mid)ans=min(ans,f[i]);
		while(l<r&&f[q[r-1]]>f[i])r--;
		q[r++]=i;
	}
	for(int i=n-mid;i<=n;i++)ans=min(ans,f[i]);
	return ans<=t;
}
int main()
{
	cin>>n>>t;
	for(int i=1;i<=n;i++)cin>>a[i];
	int l=0,r=n,ans=0x3f3f3f3f;
	while(l<=r)
	{
		int mid=(l+r)/2;
		if(check(mid)==1)r=mid-1,ans=mid;
		else l=mid+1;
	}
	cout<<ans;
	return 0;
}

 

posted @   永韶  阅读(6)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10亿数据,如何做迁移?
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 推荐几款开源且免费的 .NET MAUI 组件库
· 易语言 —— 开山篇
· Trae初体验
点击右上角即可分享
微信分享提示