目录
- 绿色通道
- 最大连续和
- 修剪草坪
- 旅行问题
-
绿色通道
已经讲了好多遍了(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]));
}
自己没写
-
旅行问题
作业