三月专题Dp专练
Posted _yrh
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了三月专题Dp专练相关的知识,希望对你有一定的参考价值。
我太菜了
如果您可以吊打我 勿喷!!!
单调队列优化Dp
P1440 求m区间内的最小值
代码:
#include <iostream> #include <cstdio> #include <algorithm> //#include <windows.h> #define ll long long #define rg register #define ull unsigned long long using namespace std; int n,m; int k,tot,head=1,tail=0; int a[2000009],q[2000009]; inline int read() { int x=0,f=1; char ch; while (ch < ‘0‘ || ch > ‘9‘) {if (ch==‘-‘)f = -1;ch = getchar();} while (ch >= ‘0‘ && ch <= ‘9‘){x = x*10+ch-‘0‘;ch = getchar();} return f*x; } int main() { n=read(),m=read(); for(rg int i=1;i<=n;i++) a[i]=read(); for(rg int i=1;i<=n;i++) { printf("%d ",a[q[head]]); while(i-q[head]+1>m&&head<=tail) head++; while(a[i]<a[q[tail]]&&head<=tail) tail--; q[++tail]=i; } //system("pause"); return 0; }
P1886 滑动窗口
代码:
#include<bits/stdc++.h> using namespace std; #define re register int #define ll long long #define maxn 1000009 #define maxm inline ll read() { ll x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=(x<<1)+(x<<3)+(ll)(ch-‘0‘);ch=getchar();} return x*f; } int q[maxn],a[maxn]; int n,m,k,ans,tot,head,tail; void Ask_MIN() { head=1,tail=0; for(int i=1;i<=n;i++) { while(head<=tail&&i-q[head]+1>m) head++; while(head<=tail&&a[q[tail]]>=a[i]) tail--; q[++tail]=i; if(i>=m) printf("%d ",a[q[head]]); } } void Ask_MAX() { head=1,tail=0; for(int i=1;i<=n;i++) { while(head<=tail&&i-q[head]+1>m) head++; while(head<=tail&&a[q[tail]]<=a[i]) tail--; q[++tail]=i; if(i>=m) printf("%d ",a[q[head]]); } } int main() { n=read(),m=read(); for(int i=1;i<=n;i++) a[i]=read(); Ask_MIN(); Ask_MAX(); return 0; }
P2629 好消息,坏消息
代码:
#include<bits/stdc++.h> using namespace std; #define re register int #define ll long long #define maxn 1000009 #define maxm inline ll read() { ll x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=(x<<1)+(x<<3)+(ll)(ch-‘0‘);ch=getchar();} return x*f; } int sum[maxn<<1],q[maxn<<1],a[maxn<<1]; int n,m,k,ans,tot,head,tail; int main() { n=read(); for(int i=1;i<=n;i++) a[i]=read(),a[i+n]=a[i]; for(int i=1;i<=2*n;i++) sum[i]=sum[i-1]+a[i]; head=1,tail=0; for(int i=1;i<=n*2-1;i++) { while(head<=tail&&i-q[head]+1>n) head++; while(head<=tail&&sum[i]<=sum[q[tail]]) tail--; q[++tail]=i; if(i>=n&&sum[q[head]]-sum[i-n]>=0) ans++; } printf("%d ",ans); return 0; }
P1714 切蛋糕
代码:
#include<bits/stdc++.h> using namespace std; #define re register int #define ll long long #define maxn 500009 #define maxm inline ll read() { ll x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=(x<<1)+(x<<3)+(ll)(ch-‘0‘);ch=getchar();} return x*f; } int sum[maxn],q[maxn]; int n,m,k,ans,tot,mx,head,tail; int main() { n=read(),m=read(); for(int i=1;i<=n;i++) { int x=read(); sum[i]=sum[i-1]+x; } head=1,tail=0; for(int i=1;i<=n;i++) { while(head<=tail&&i-q[head]>m) head++; ans=max(ans,sum[i]-sum[q[head]]); while(head<=tail&&sum[q[tail]]>=sum[i]) tail--; q[++tail]=i; } printf("%d ",ans); }
以上是关于三月专题Dp专练的主要内容,如果未能解决你的问题,请参考以下文章