P5858 「SWTR-03」Golden Sword

Jennie

一个比较水的动态规划

\(dp[i][j]=max(dp[i][j],dp[i-1][k])+a_i*j\quad k\in [j-1,j-1+s]\)

然后这个玩意可以用有限队列

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define int long long
using namespace std;
int n,w,s;
int a[100001];
int dp[5005][5005];
deque<int> q;
int ans=-1008600110086001;
signed main(){
	scanf("%lld%lld%lld",&n,&w,&s);
	for(int i=1;i<=n;++i){
		scanf("%lld",&a[i]);
	}
	memset(dp,-0x3f,sizeof(dp));
	dp[0][0]=0;
	for(int i=1;i<=n;++i){
		int r=0;
		for(int j=1;j<=min(i,w);++j){
			while(!q.empty()&&q.front()<j-1){
					q.pop_front();
				}
			while(r<=w&&r<=j-1+s){
				while(!q.empty()&&dp[i-1][q.back()]<=dp[i-1][r]){
					q.pop_back();
				}
				q.push_back(r);
				r++;
			}
			dp[i][j]=dp[i-1][q.front()]+a[i]*j;
		}
		while(!q.empty())
		q.pop_back();
	}
	for(int i=1;i<=w;++i){
		ans=max(ans,dp[n][i]);
		//cout<<dp[n][i]<<endl;
	}
	cout<<ans;
	return 0;
}
posted @ 2021-09-12 21:34  Simex  阅读(99)  评论(0编辑  收藏  举报