【专题】单调队列/斜率优化DP
来源:互联网 发布:gta4渣优化 编辑:程序博客网 时间:2024/05/22 05:09
一、单调队列
志愿者选拔 O(n)
struct STU{ char name[7]; int rp;};int que[2111111];int idx[2111111];int main(){ int T,head,tail; char gs[111]; scanf("%d",&T); while (T--) { int cas,cnt; head=tail=0; cas=cnt=0; while (scanf("%s",gs)) { if (strcmp(gs,"END")==0) break; if (strcmp(gs,"C")==0) { cnt++; STU tmp; scanf("%s%d",tmp.name,&tmp.rp); while (head<tail&&que[tail-1]<=tmp.rp) tail--; idx[tail]=cnt; que[tail++]=tmp.rp; } if (strcmp(gs,"G")==0) { cas++; if (idx[head]<=cas) head++; } if (strcmp(gs,"Q")==0) { if (head<tail) cout<<que[head]<<endl; else cout<<-1<<endl; } } } return 0;}
Sliding Window O(n)
#include <iostream>#include <cstdio>#include <vector>using namespace std;const int maxn=1111111;int a[maxn];int que[maxn];int idx[maxn];int main(){ int n,k; int head,tail,cas; while (~scanf("%d%d",&n,&k)) { for (int i=0;i<n;i++) scanf("%d",&a[i]); head=tail=cas=0; for (int i=0;i<n;i++) { while (head<tail&&que[tail-1]>=a[i]) tail--; idx[tail]=i; que[tail++]=a[i]; while (head<tail&&i-idx[head]>=k) head++; if (i>=k-1) cout<<que[head]<<" "; else if (i>=k-1&&i==n-1) cout<<que[head]; } cout<<endl; head=tail=cas=0; for (int i=0;i<n;i++) { while (head<tail&&que[tail-1]<=a[i]) tail--; idx[tail]=i; que[tail++]=a[i]; while (head<tail&&i-idx[head]>=k) head++; if (i>=k-1&&i<n-1) cout<<que[head]<<" "; else if (i>=k-1&&i==n-1) cout<<que[head]; } cout<<endl; } return 0;}
Max Sum of Max-K-sub-sequence O(n)
#include <iostream>#include <cstdio>#include <cstring>using namespace std;int a[411111];int f[411111];int que[1111111];int pt[1111111];int n,k;int T;int head,tail;int sum[411111];int max_sum,start,end;int main(){ scanf("%d",&T); while (T--) { memset(f,0,sizeof(f)); memset(que,0,sizeof(que)); memset(pt,0,sizeof(pt)); memset(sum,0,sizeof(sum)); scanf("%d%d",&n,&k); for (int i=1;i<=n;i++) { scanf("%d",&a[i]); a[i+n]=a[i]; } for (int i=1;i<=n+k;i++) { sum[i]+=sum[i-1]+a[i]; } //f[i]=max(sum[i]-sum[k]); head=tail=0; max_sum=start=end=-1e9; for (int i=1;i<=n+k;i++) { while ((head<tail)&&(i-pt[head]>k)) head++; while ((head<tail)&&(sum[i-1]<=que[tail-1])) tail--; que[tail]=sum[i-1],pt[tail++]=i-1; f[i]=sum[i]-que[head]; if (f[i]>max_sum) { max_sum=f[i]; start=pt[head]+1; end=i; } } if (start>n) start=start-n; if (end>n) end=end-n; printf("%d %d %d\n",max_sum,start,end); } return 0;}
二、单调队列dp
Trade O(n)
/** head-file **/#include <iostream>#include <fstream>#include <sstream>#include <iomanip>#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <vector>#include <queue>#include <stack>#include <list>#include <set>#include <map>#include <algorithm>/** define-for **/#define REP(i, n) for (int i=0;i<int(n);++i)#define FOR(i, a, b) for (int i=int(a);i<int(b);++i)#define DWN(i, b, a) for (int i=int(b-1);i>=int(a);--i)#define REP_1(i, n) for (int i=1;i<=int(n);++i)#define FOR_1(i, a, b) for (int i=int(a);i<=int(b);++i)#define DWN_1(i, b, a) for (int i=int(b);i>=int(a);--i)#define REP_N(i, n) for (i=0;i<int(n);++i)#define FOR_N(i, a, b) for (i=int(a);i<int(b);++i)#define DWN_N(i, b, a) for (i=int(b-1);i>=int(a);--i)#define REP_1_N(i, n) for (i=1;i<=int(n);++i)#define FOR_1_N(i, a, b) for (i=int(a);i<=int(b);++i)#define DWN_1_N(i, b, a) for (i=int(b);i>=int(a);--i)/** define-useful **/#define clr(x,a) memset(x,a,sizeof(x))#define sz(x) int(x.size())#define see(x) cerr<<#x<<" "<<x<<endl#define se(x) cerr<<" "<<x#define pb push_back#define mp make_pair/** test **/#define Display(A, n, m) { \ REP(i, n){ \ REP(j, m) cout << A[i][j] << " "; \ cout << endl; \ } \}#define Display_1(A, n, m) { \ REP_1(i, n){ \ REP_1(j, m) cout << A[i][j] << " "; \ cout << endl; \ } \}using namespace std;/** typedef **/typedef long long LL;/** Add - On **/const int direct4[4][2]={ {0,1},{1,0},{0,-1},{-1,0} };const int direct8[8][2]={ {0,1},{1,0},{0,-1},{-1,0},{1,1},{1,-1},{-1,1},{-1,-1} };const int direct3[6][3]={ {1,0,0},{0,1,0},{0,0,1},{-1,0,0},{0,-1,0},{0,0,-1} };const int MOD = 1000000007;const int INF = 0x3f3f3f3f;const long long INFF = 1LL << 60;const double EPS = 1e-9;const double OO = 1e15;const double PI = acos(-1.0); //M_PI;const int maxn=2222;int f[maxn][maxn];int AP[maxn],BP[maxn],AS[maxn],BS[maxn];int MaxP,W,T;/** f[i][j]=max(f[i-1][j],f[i-W-1][k]-AP[i]*(j-k),f[i-W-1][k]+BP[i]*(k-j)) f[i-W-1][k]-AP[i]*(j-k) =f[i-W-1][k]+AP[i]*k-AP[i]*j f[i-W-1][k]+BP[i]*(k-j) =f[i-W-1][k]+BP[i]*k-BP[i]*j**/int que[maxn];int idx[maxn];int main(){ int CAS; int head,tail,ans; scanf("%d",&CAS); while (CAS--) { scanf("%d%d%d",&T,&MaxP,&W); REP_1(i,T) { scanf("%d%d%d%d",&AP[i],&BP[i],&AS[i],&BS[i]); } REP_1(i,MaxP) f[0][i]=-INF; f[0][0]=0; ans=0; FOR_1(i,1,T) { FOR_1(j,0,MaxP) f[i][j]=f[i-1][j]; if (i-W-1<1) { FOR_1(j,0,AS[i]) f[i][j]=max(f[i][j],-AP[i]*j); continue; } head=tail=0; FOR_1(j,0,MaxP) { while (head<tail&&que[tail-1]<=f[i-W-1][j]+AP[i]*j) tail--; que[tail]=f[i-W-1][j]+AP[i]*j; idx[tail++]=j; while (head<tail&&j-idx[head]>AS[i]) head++; f[i][j]=max(f[i][j],que[head]-AP[i]*j); ans=max(ans,f[i][j]); } head=tail=0; DWN_1(j,MaxP,0) { while (head<tail&&que[tail-1]<=f[i-W-1][j]+BP[i]*j) tail--; que[tail]=f[i-W-1][j]+BP[i]*j; idx[tail++]=j; while (head<tail&&idx[head]-j>BS[i]) head++; f[i][j]=max(f[i][j],que[head]-BP[i]*j); ans=max(ans,f[i][j]); } } cout<<ans<<endl; } return 0;}
SubsequenceO(n)
/** head-file **/#include <iostream>#include <fstream>#include <sstream>#include <iomanip>#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <vector>#include <queue>#include <stack>#include <list>#include <set>#include <map>#include <algorithm>/** define-for **/#define REP(i, n) for (int i=0;i<int(n);++i)#define FOR(i, a, b) for (int i=int(a);i<int(b);++i)#define DWN(i, b, a) for (int i=int(b-1);i>=int(a);--i)#define REP_1(i, n) for (int i=1;i<=int(n);++i)#define FOR_1(i, a, b) for (int i=int(a);i<=int(b);++i)#define DWN_1(i, b, a) for (int i=int(b);i>=int(a);--i)#define REP_N(i, n) for (i=0;i<int(n);++i)#define FOR_N(i, a, b) for (i=int(a);i<int(b);++i)#define DWN_N(i, b, a) for (i=int(b-1);i>=int(a);--i)#define REP_1_N(i, n) for (i=1;i<=int(n);++i)#define FOR_1_N(i, a, b) for (i=int(a);i<=int(b);++i)#define DWN_1_N(i, b, a) for (i=int(b);i>=int(a);--i)/** define-useful **/#define clr(x,a) memset(x,a,sizeof(x))#define sz(x) int(x.size())#define see(x) cerr<<#x<<" "<<x<<endl#define se(x) cerr<<" "<<x#define pb push_back#define mp make_pair/** test **/#define Display(A, n, m) { \ REP(i, n){ \ REP(j, m) cout << A[i][j] << " "; \ cout << endl; \ } \}#define Display_1(A, n, m) { \ REP_1(i, n){ \ REP_1(j, m) cout << A[i][j] << " "; \ cout << endl; \ } \}using namespace std;/** typedef **/typedef long long LL;/** Add - On **/const int direct4[4][2]={ {0,1},{1,0},{0,-1},{-1,0} };const int direct8[8][2]={ {0,1},{1,0},{0,-1},{-1,0},{1,1},{1,-1},{-1,1},{-1,-1} };const int direct3[6][3]={ {1,0,0},{0,1,0},{0,0,1},{-1,0,0},{0,-1,0},{0,0,-1} };const int MOD = 1000000007;const int INF = 0x3f3f3f3f;const long long INFF = 1LL << 60;const double EPS = 1e-9;const double OO = 1e15;const double PI = acos(-1.0); //M_PI;const int maxn=110000;int a[maxn];typedef pair<int,int> PII;deque<PII>q1,q2;int main(){ int n,m,k; int ans,now; while (~scanf("%d%d%d",&n,&m,&k)) { ans=0; now=0; q1.clear(); q2.clear(); REP(i,n) { scanf("%d",&a[i]); while (!q1.empty()&&q1.back().first<=a[i]) q1.pop_back(); q1.push_back(mp(a[i],i)); while (!q2.empty()&&q2.back().first>=a[i]) q2.pop_back(); q2.push_back(mp(a[i],i)); while (!q1.empty()&&!q2.empty()&&q1.front().first-q2.front().first>k) { if (q1.front().second<q2.front().second) { now=q1.front().second+1; q1.pop_front(); } else { now=q2.front().second+1; q2.pop_front(); } } if (!q1.empty()&&!q2.empty()&&q1.front().first-q2.front().first>=m) ans=max(ans,i-now+1); } printf("%d\n",ans); } return 0;}
其他题目
MUTC8 E- One hundred layer 单调队列dp
MUTC7 C - Dragon Ball 单调队列dp
三、斜率优化
MAX Average Problem O(n)
/** head-file **/#include <iostream>#include <fstream>#include <sstream>#include <iomanip>#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <vector>#include <queue>#include <stack>#include <list>#include <set>#include <map>#include <algorithm>/** define-for **/#define REP(i, n) for (int i=0;i<int(n);++i)#define FOR(i, a, b) for (int i=int(a);i<int(b);++i)#define DWN(i, b, a) for (int i=int(b-1);i>=int(a);--i)#define REP_1(i, n) for (int i=1;i<=int(n);++i)#define FOR_1(i, a, b) for (int i=int(a);i<=int(b);++i)#define DWN_1(i, b, a) for (int i=int(b);i>=int(a);--i)#define REP_N(i, n) for (i=0;i<int(n);++i)#define FOR_N(i, a, b) for (i=int(a);i<int(b);++i)#define DWN_N(i, b, a) for (i=int(b-1);i>=int(a);--i)#define REP_1_N(i, n) for (i=1;i<=int(n);++i)#define FOR_1_N(i, a, b) for (i=int(a);i<=int(b);++i)#define DWN_1_N(i, b, a) for (i=int(b);i>=int(a);--i)/** define-useful **/#define clr(x,a) memset(x,a,sizeof(x))#define sz(x) int(x.size())#define see(x) cerr<<#x<<" "<<x<<endl#define se(x) cerr<<" "<<x#define pb push_back#define mp make_pair/** test **/#define Display(A, n, m) { \ REP(i, n){ \ REP(j, m) cout << A[i][j] << " "; \ cout << endl; \ } \}#define Display_1(A, n, m) { \ REP_1(i, n){ \ REP_1(j, m) cout << A[i][j] << " "; \ cout << endl; \ } \}using namespace std;/** typedef **/typedef long long LL;/** Add - On **/const int direct4[4][2]={ {0,1},{1,0},{0,-1},{-1,0} };const int direct8[8][2]={ {0,1},{1,0},{0,-1},{-1,0},{1,1},{1,-1},{-1,1},{-1,-1} };const int direct3[6][3]={ {1,0,0},{0,1,0},{0,0,1},{-1,0,0},{0,-1,0},{0,0,-1} };const int MOD = 1000000007;const int INF = 0x3f3f3f3f;const long long INFF = 1LL << 60;const double EPS = 1e-9;const double OO = 1e15;const double PI = acos(-1.0); //M_PI;const int maxn=111111;int a[maxn];int sum[maxn];int que[maxn];int head,tail;int getin(){ char ch=' '; while (ch<'0'||ch>'9') ch=getchar(); int x=0; while (ch>='0'&&ch<='9') { x=x*10+ch-'0'; ch=getchar(); } return x;}double getup(int i,int j){ return sum[i]-sum[j];}int getdown(int i,int j){ return i-j;}long long cross(int a,int b,int c){ long long x1=b-a; long long y1=sum[b]-sum[a]; long long x2=c-b; long long y2=sum[c]-sum[b]; return x1*y2-y1*x2;}int dbsearch(int l,int r,int i){ while (l<r) { int mid=(l+r)/2; if (cross(que[mid],que[mid+1],i)<0) r=mid; else l=mid+1; } return l;}int main(){ int n,k; while (~scanf("%d%d",&n,&k)) { sum[0]=0; REP_1(i,n) { a[i]=getin(); sum[i]=sum[i-1]+a[i]; } head=tail=0; que[tail++]=0; double ans=0; FOR_1(i,k,n) { int j=i-k; while (head+1<tail&&cross(que[tail-2],que[tail-1],j)<0) tail--; que[tail++]=j; int tmp=dbsearch(0,tail-1,i); double f=double(sum[i]-sum[que[tmp]])/(i-que[tmp]); ans=max(ans,f); } printf("%0.2f\n",ans); } return 0;}
Print ArticleO(n)
/** head-file **/#include <iostream>#include <fstream>#include <sstream>#include <iomanip>#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <vector>#include <queue>#include <stack>#include <list>#include <set>#include <map>#include <algorithm>/** define-for **/#define REP(i, n) for (int i=0;i<int(n);++i)#define FOR(i, a, b) for (int i=int(a);i<int(b);++i)#define DWN(i, b, a) for (int i=int(b-1);i>=int(a);--i)#define REP_1(i, n) for (int i=1;i<=int(n);++i)#define FOR_1(i, a, b) for (int i=int(a);i<=int(b);++i)#define DWN_1(i, b, a) for (int i=int(b);i>=int(a);--i)#define REP_N(i, n) for (i=0;i<int(n);++i)#define FOR_N(i, a, b) for (i=int(a);i<int(b);++i)#define DWN_N(i, b, a) for (i=int(b-1);i>=int(a);--i)#define REP_1_N(i, n) for (i=1;i<=int(n);++i)#define FOR_1_N(i, a, b) for (i=int(a);i<=int(b);++i)#define DWN_1_N(i, b, a) for (i=int(b);i>=int(a);--i)/** define-useful **/#define clr(x,a) memset(x,a,sizeof(x))#define sz(x) int(x.size())#define see(x) cerr<<#x<<" "<<x<<endl#define se(x) cerr<<" "<<x#define pb push_back#define mp make_pair/** test **/#define Display(A, n, m) { \ REP(i, n){ \ REP(j, m) cout << A[i][j] << " "; \ cout << endl; \ } \}#define Display_1(A, n, m) { \ REP_1(i, n){ \ REP_1(j, m) cout << A[i][j] << " "; \ cout << endl; \ } \}using namespace std;/** typedef **/typedef long long LL;/** Add - On **/const int direct4[4][2]={ {0,1},{1,0},{0,-1},{-1,0} };const int direct8[8][2]={ {0,1},{1,0},{0,-1},{-1,0},{1,1},{1,-1},{-1,1},{-1,-1} };const int direct3[6][3]={ {1,0,0},{0,1,0},{0,0,1},{-1,0,0},{0,-1,0},{0,0,-1} };const int MOD = 1000000007;const int INF = 0x3f3f3f3f;const long long INFF = 1LL << 60;const double EPS = 1e-9;const double OO = 1e15;const double PI = acos(-1.0); //M_PI;/** f[i]=min( f[j]+(sum[i]-sum[j])^2+M ) y为f[j]+sum[j]^2,x为2*sum[j],斜率为sum[i],截距为f[i]**/const int maxn=550000;int n,m;int a[maxn];int f[maxn];int que[maxn];int head,tail;int sum[maxn];int gety(int j){return f[j]+sum[j]*sum[j];}int getx(int j){return 2*sum[j];}int dp_sol(int i,int j){return f[j]+(sum[i]-sum[j])*(sum[i]-sum[j])+m;}bool cmp_idx(int i,int j,int k){ return (gety(i)-gety(j))*(getx(j)-getx(k))<=(gety(j)-gety(k))*(getx(i)-getx(j));}int main(){ while (~scanf("%d%d",&n,&m)) { memset(f,0,sizeof(f)); sum[0]=0; REP_1(i,n) { scanf("%d",&a[i]); sum[i]=sum[i-1]+a[i]; } head=tail=0; que[tail++]=0; f[0]=0; for (int i=1;i<=n;i++) { while (tail-head>1&&dp_sol(i,que[head])>=dp_sol(i,que[head+1])) head++; f[i]=dp_sol(i,que[head]); while (tail-head>1&&cmp_idx(i,que[tail-1],que[tail-2])) tail--; que[tail++]=i; } cout<<f[n]<<endl; } return 0;}
其他题目
Codeforces Round #189 (Div. 2) 解题报告
四、BST解决不单调的dp问题
- 【专题】单调队列/斜率优化DP
- 单调队列,斜率优化dp 专题
- 斜率优化+单调队列优化DP
- 斜率优化+单调队列优化DP<转>
- 单调队列+斜率优化的DP
- 【专辑】单调队列+斜率优化的DP
- 【整理】斜率or单调队列优化dp
- ##单调队列、斜率优化##
- 关于DP的单调队列优化和斜率优化区别
- 模型化理解单调队列优化和斜率优化DP
- dp的斜率优化与单调队列优化
- 【DP】【斜率优化】【单调队列优化】Gift 题解
- hdu3507 Print Article 单调队列斜率优化DP
- 【GDOI2014模拟】服务器 (斜率单调队列优化Dp)
- [HNOI2008]玩具装箱-DP斜率优化-单调队列-学习笔记
- 单调队列优化专题
- 斜率优化dp专题学习
- dp部分总结(单调队列,四边形优化,斜率优化,树形dp)
- ERP系统容灾方案对ERP生产系统的影响
- ubuntu 制作USB启动盘
- linux如何查找文件或者目录的位置相关命令汇总
- android基础知识12:android自动化测试04—Robotium:实例(上)
- 如何用T-SQL判断SQL语法是否正确
- 【专题】单调队列/斜率优化DP
- Comparable排序(备忘)
- java.io.Serializable这个接口
- android基础知识12:android自动化测试03—基于junit的android测试框架03
- 如何使用jQuery ui 分享心得
- Triangle CrackMe
- POJ 3233 Matrix Power Series(矩阵快速幂+二分求和)
- RTSP resources integration
- 程序员练级攻略