題目描述
據說在紅霧異變時,博麗靈夢單身前往紅魔館,用十分強硬的手段將事件解決了。
然而當時靈夢在Power達到MAX之前,不具有“上線收點”的能力,所以她想要知道她能收集多少P點,然而這個問題她答不上來,於是她找到了學OI的你。
可以把遊戲界面理解成一個N行M列的棋盤,有K個格子上有P點,其價值爲val(i,j)初始靈夢可以選擇在第一行的任意一個格子出發,每秒她必須下移一格。
靈夢具有一個左右移動的速度T,可以使她每秒向左或右移動至多T格,也可以不移動,並且不能折返。移動可視爲瞬間完成,不經過路途上的點,只能獲得目標格子的P點。
求最終她能獲得的POWER值最大是多少?
(p點不是有上限的麼..)
輸入輸出格式
輸入格式:
第一行四個數字,N,M,K,T
接下來K行每行3個數字x,y,v,代表第x行第y列有一個val爲v的P點,數據保證一個格子上最多隻有1個P點。
輸出格式:
一個數字
f[i][j]表示到達f[i][j]收集的最大p點
維護區間最大值單調隊列
http://blog.csdn.net/flanoc/article/details/72904458
超偷懶的單調隊列總結
#include<bits/stdc++.h>
#define fer(i,j,n) for(int i=j;i<=n;i++)
#define far(i,j,n) for(int i=j;i>=n;i--)
#define ll long long
const int maxn=4010;
const int INF=1e9+7;
using namespace std;
/*----------------------------------------------------------------------------*/
inline ll read()
{
char ls;ll x=0,sng=1;
for(;ls<'0'||ls>'9';ls=getchar())if(ls=='-')sng=-1;
for(;ls>='0'&&ls<='9';ls=getchar())x=x*10+ls-'0';
return x*sng;
}
/*----------------------------------------------------------------------------*/
int f[maxn][maxn],a[maxn][maxn];
int n,m,K,T;
int q[maxn],h,t,maxx;
int main()
{
scanf("%d%d%d%d",&n,&m,&K,&T);
fer(i,1,K)
{
int x=read(),y=read();
a[x][y]=read();
}
fer(i,1,m)f[1][i]=a[1][i];
fer(i,2,n)
{
h=1;t=0;
fer(j,1,min(m,T+1))
{
while(h<=t&&f[i-1][j]>=f[i-1][q[t]])t--;
q[++t]=j;
}
fer(j,1,m)
{
if(j+T<=m)
{
while(h<=t&&f[i-1][j+T]>=f[i-1][q[t]])t--;
q[++t]=j+T;
}
if(q[h]<j-T)h++;
f[i][j]=f[i-1][q[h]]+a[i][j];
}
}
fer(i,1,m)maxx=max(maxx,f[n][i]);
cout<<maxx;
return 0;
}