2025/1/20课堂记录

目录

  1. 绿色通道
  2. 最大连续和
  3. 修剪草坪
  4. 旅行问题

已经讲了好多遍了(2025/1/11,2024/12/21),现在详细捋一下思路

首先上来,最有辨识度的就是“最长”空题段“最小”

就是最大值最小——二分答案

木材加工闻着味就过来了(详见2024/12/28)

但这还和木材加工不太一样,check部分不一样

这里要算的是空mid道题,用t分钟能不能实现

那么在固定空mid道题的情况下,从前往后算最小花费时长

f[i]=min(f[i-1],f[i-2],f[i-3]...f[j]...f[i-mid],f[i-mid-1])<—括号里面共有mid个数

用一个小dp就能解决啦

至于单调队列优化,还是看之前讲的吧
#include<iostream>
using namespace std;
int dp[51000],a[51000],n,t;
int check(int mid)
{
    for(int i=1;i<=mid+1;i++)dp[i]=a[i];//单调队列优化后,一个补0就能解决这行 
    for(int i=mid+2;i<=n;i++)
	{
	    dp[i]=0x3f3f3f3f;
		for(int j=i-mid-1;j<=i-1;j++)dp[i]=min(dp[j]+a[i],dp[i]);	
    } 
    int ans=0x3f3f3f3f;
    for(int i=n-mid;i<=n;i++)ans=min(ans,dp[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))r=mid-1,ans=mid;
		else l=mid+1;
	}
	cout<<ans<<endl;
	return 0; 
}

也是讲了好多遍了(发现今天的课和2024/12/21的课一模一样)

计算每一个i之前一段距离之和(a[q[l+1]]+a[q[l+2]]+...+a[i-1]+a[i])

可以直接用a[i]-a[q[l]]计算

每一次a[i]都是固定的

想要让a[i]-a[q[l]]尽可能大,那么a[q[l]]就要尽可能小

所以维护的是a[q[l]]的单调递增,那就要把比新来的更大的删掉

        while(l<r&&a[q[r-1]]>a[i])r--;

剩下套模板~~

~~~~~~~
 #include<iostream>
using namespace std;
int n,m,a[200010],q[200010];
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		int x;
		cin>>x;
		a[i]=a[i-1]+x;
	}
	int l=0,r=1,ans=-0x3f3f3f3f;
	for(int i=1;i<=n;i++)
	{
		while(l<r&&q[l]<i-m)l++;
		ans=max(ans,a[i]-a[q[l]]);
		while(l<r&&a[q[r-1]]>a[i])r--;
		q[r++]=i;
	}
	cout<<ans;
	return 0;
}

(好了现在和2024/12/21不一样了)

朴素dp之前写过,这里不写了

这里给一个单调队列优化吧
 //https://blog.csdn.net/ybC202444/article/details/127161633
//修建草坪,朴素dp 
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 5 ;
#define  ll  long long
ll n,k,a[MAXN],q[MAXN];
ll s[MAXN],dp[MAXN][2];
ll l,r; 
// dp[i][0]: 第i个数不要,1-i之间,最大效率;
// dp[i][1]: 第i个数要,1-i之间,最大效率;
int main()
{
	cin>>n>>k;
	for(ll i=1;i<=n;i++)
	{
		cin>>a[i];
		s[i]=s[i-1]+a[i];
	}
	l=0,r=0;
	q[l]=0,r=1;// 队头插入0编号
	//单调队列维护 
	for(ll i=1;i<=n;i++)
	{
		while(l<r&&q[l]<i-k)l++;
		dp[i][0]=max(dp[i-1][1],dp[i-1][0]);
		dp[i][1]=dp[q[l]][0]+s[i]-s[q[l]];//j不要,j+1---i要
		//dp[i][1]=(dp[q[l]][0]-s[q[l]]) + s[i]
		//f[i]=max/min(g(j))+a[i] 
		//维护递减: dp[j][0]-s[j]   
		while(l<r&&dp[q[r-1]][0]-s[q[r-1]]<dp[i][0]-s[i])r--;
		q[r++]=i;
	}
	printf("%lld\n",max(dp[n][1],dp[n][0]));
}

自己没写


作业

 

posted @   永韶  阅读(24)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek-R1本地部署如何选择适合你的版本?看这里
· 传国玉玺易主,ai.com竟然跳转到国产AI
· 自己如何在本地电脑从零搭建DeepSeek!手把手教学,快来看看! (建议收藏)
· 我们是如何解决abp身上的几个痛点
· 普通人也能轻松掌握的20个DeepSeek高频提示词(2025版)
点击右上角即可分享
微信分享提示