动态规划的优化1

作业介绍

#include <bits/stdc++.h>
using namespace std;
const int N = 1e6+5;
int n,a[N],k;
int q[N],tail=-1,head=0;
int main(){
	cin>>n>>k;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	for(int i=1;i<=n;i++){
		//1.队尾出队
		while(tail>=head && a[i]<=a[q[tail]])--tail;
		q[++tail] = i;
		while(tail>=head && i-q[head]+1>k)head++;
		if(i>=k)cout<<a[q[head]]<<" ";
	}
	cout<<endl;
	tail = -1,head = 0;
	for(int i=1;i<=n;i++){
		while(tail>=head && a[i]>=a[q[tail]])tail--;
		q[++tail] = i;
		while(tail>=head && i-q[head]+1>k)head++;
		if(i>=k)cout<<a[q[head]]<<" ";
	}
	return 0;
}
/*
f[i] = sum[i]-sum[j]  i-k<=j<i
选j+1到i块蛋糕 i-j<=k  j>=i-k
*/
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 5e5+5;
int n,a[N],sum[N],k;
int q[N],tail=-1,head=0;
signed main(){
	cin>>n>>k;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		sum[i] = sum[i-1]+a[i];
	}
	int res = -1e18;
	for(int i=1;i<=n;i++){
		while(tail>=head && sum[i-1]<=sum[q[tail]])tail--;
		q[++tail] = i-1;
		while(tail>=head && q[head]<i-k)head++;
		res = max(res,sum[i]-sum[q[head]]);
	}
	cout<<res<<endl;
	return 0;
}
/*
f[i] = f[i-1]+x,f[j]+y+2*j*x-i*x  i/2<=j<i
*/
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e7+5;
int n,x,y,f[N];
int q[N],tail=-1,head=0;
signed main(){
	cin>>n>>x>>y;
	f[1] = x;
	
	for(int i=2;i<=n;i++){
		while(tail>=head && f[i-1]+2*(i-1)*x<=f[q[tail]]+2*q[tail]*x)--tail;
		q[++tail] = i-1;
		while(tail>=head && q[head]<i/2.0)head++;
		f[i] = min(f[i-1]+x,f[q[head]]+y+(2*q[head]-i)*x);
	}
	cout<<f[n]<<endl;
	return 0;
}
/*
f[i]前i头奶牛的最大效率
//i-j<=k
f[i] = f[j-1]-sum[j]+ (sum[i])   i-k<=j<=i
*/
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N =1e5+5;
int n,k,a[N],sum[N];
int q[N],tail=-1,head=0,f[N];
signed main(){
	cin>>n>>k;
	for(int i=1;i<=n;i++){
		cin>>sum[i];
		sum[i]+=sum[i-1];
	}
	q[++tail] = 0;
	for(int i=1;i<=n;i++){
		while(tail>=head && f[i-1]-sum[i]>=f[q[tail]-1]-sum[q[tail]])--tail;
		q[++tail] = i;
		while(tail>=head && q[head]<i-k)head++;
		int j = q[head];
		f[i] = f[j-1]+sum[i]-sum[j];
	}
	cout<<f[n]<<endl;
	return 0;
}
/*
f[i][j]第i天持有j张股票的时候赚的最多的钱
f[i][j] = -Ap[i]*j
f[i][j] = f[i-1][j]

f[i][j] = f[i-w-1][k]+k*Ap[i] -j*Ap[i]      j-As[i]<=k<=j

f[i][j] = f[i-w-1][k]+k*Bp[i]-j*Bp[i]       j+Bs[i]>=k>=j
*/
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2005;
int n,MaxP,w;
int As[N],Bs[N],Ap[N],Bp[N],f[N][N];
int q[N],tail=-1,head=0;
signed main(){
	cin>>n>>MaxP>>w;w++;
	for(int i=1;i<=n;i++){
		cin>>Ap[i]>>Bp[i]>>As[i]>>Bs[i];
	}
	memset(f,0xcf,sizeof(f));
	f[0][0] = 0;
	for(int i=1;i<=n;i++){
		for(int j=0;j<=MaxP;j++){
			if(j<=As[i])f[i][j] = -Ap[i]*j;
			f[i][j] = max(f[i][j],f[i-1][j]);
		}
		if(i>=w){
			tail=-1,head=0;
			for(int j=0;j<=MaxP;j++){
				while(tail>=head && f[i-w][j]+j*Ap[i]>=f[i-w][q[tail]]+q[tail]*Ap[i])--tail;
				q[++tail] = j;
				while(tail>=head && q[head]<j-As[i])head++;
				f[i][j] = max(f[i][j],f[i-w][q[head]]+q[head]*Ap[i]-j*Ap[i]);
			}
			tail=-1,head=0;
			for(int j=MaxP;j>=0;j--){
				while(tail>=head && f[i-w][j]+j*Bp[i]>=f[i-w][q[tail]]+q[tail]*Bp[i])--tail;
				q[++tail] = j;
				while(tail>=head && q[head]>j+Bs[i])head++;
				f[i][j] = max(f[i][j],f[i-w][q[head]]+Bp[i]*q[head]-j*Bp[i]);
			}
		}
	}
	int res = -1e19;
	for(int i=0;i<=MaxP;i++){
		res = max(res,f[n][i]);
	}
	cout<<res<<endl;
	return 0;
}

题目

认领作业后才可以查看作业内容。
状态
正在进行…
题目
11
开始时间
2026-4-18 0:00
截止时间
2026-4-26 23:59
可延期
24 小时