UESTC1132 醬神賞花 【DP+單調隊列】

【題目大意】

中文題面。

需要注意的是AI,BI,TI和題面裏的輸入順序不同

【解題思路】

由於bi是常數,所以可以用Σb來減去答案即可。

所以實際上我們維護的是|x-ai|的最小值

狀態定義:dp[i][j]表示第j時刻(注意是時刻不是時間,此處的j只表明花出現的順序而不關心花出現的具體時間)人在i位置時所對應的|x-ai|的最小值

考慮轉移方程:dp[i][j]=min(dp[k][j-1]+|i-flower[j]|)其中k滿足i-Δt*d<=k<=i+Δt*d(Δt=這一時刻的時間減去上一時刻的時間)

由於|i-flower[j]|與min函數的主體k無關,所以該部分可以從min中取出

所以轉移方程轉化爲->dp[i][j]=min(dp[k][j-1])+|i-flower[j]|

其中min部分可以使用單調隊列進行處理

最後枚舉終點,求出答案

【代碼】

#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#include<ctime>
#include<cmath>
#include<cstdio>
#include<cstdlib>
//#include<conio.h>
#include<iomanip>
#define LL long long
//#define LOCAL
using namespace std;

const int N=100011;
const LL INF=2139062143;
LL n,m,d,sigma_s;
LL dp[N][101];
LL ans;
int head,tail;

int tim=0;

struct Flower{
	int t;
	int f;
}delta[N];

bool cmp(const Flower &A,const Flower &B){
	return A.t<B.t;
}

struct Handrum{
	int q[N];
	bool exist[N];
	
	void Insert(LL x,LL s){
		while (head<=tail&&dp[q[tail]][s]>=dp[x][s]) exist[q[tail--]]=false;
        q[++tail]=x;
        exist[x]=true;
	}
	
	void Clear(){
		head=0;
        tail=-1;
		memset(q,0,sizeof(q));
		memset(exist,false,sizeof(exist));
	}
	
	void Delete(LL x){
		if (exist[x]) head++;
	}
	

}que;

int main(){
#ifdef LOCAL
    freopen("UESTC1132.in","r",stdin);
#endif
    que.Clear();
    ans=INF;
    sigma_s=0;
    scanf("%lld%lld%lld",&n,&m,&d);
    for (int i=1;i<=m;++i){
    	LL pos,value;
    	scanf("%lld%lld%lld",&pos,&value,&delta[i].t);
    	delta[i].f=pos;
    	sigma_s+=value;
	}
	sort(delta+1,delta+m+1,cmp);
	for (int i=1;i<=n;++i){
		dp[i][1]=abs(i-delta[1].f);
	}
	for (int i=2;i<=m;++i){
		que.Clear();
		LL tmp=delta[i].t-delta[i-1].t;
		LL len=tmp*d;
		for (int j=1;j<=min(len,n);++j) que.Insert(j,i-1);
		for (int j=1;j<=n;++j){
			if (j+len<=n) que.Insert(j+len,i-1);
			if (j-len>1) que.Delete(j-len-1);
			dp[j][i]=dp[que.q[head]][i-1]+abs(j-delta[i].f);

		}
		
	}
	for (int i=1;i<=n;++i) ans=min(ans,dp[i][m]);
	printf("%lld\n",sigma_s-ans);
	return 0;
}

【總結】

DP+單調隊列


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章