C. Watching Fireworks is Fun
题意:
一条街道有 n n n个区域。 从左到右编号为 1 1 1到 n n n。 相邻区域之间的距离为 1 1 1。在节日期间,有 m m m次烟花要燃放。 第 i i i次烟花燃放区域为 a i a_i ai,幸福属性为 b i b_i bi,时间为 t i t_i ti。 t i ⩽ t i + 1 t_i⩽t_i+1 ti⩽ti+1
如果你在第 i i i次烟花发射时在 x ( 1 ⩽ x ⩽ n ) x(1⩽x⩽n) x(1⩽x⩽n)处,你将获得幸福值 b i − ∣ a i − x ∣ bi−|ai−x| bi−∣ai−x∣(请注意,幸福值可能是负值)。
你可以在单位时间间隔内移动最多 d d d个单位,但禁止走出主要街道。 此外,您可以在初始时刻(时间等于1时)处于任意区域,并希望最大化从观看烟花中获得的幸福总和。
题解:dp+单调队列+滚动数组优化
如果时间重叠,就直接状态转移,否则就单调队列优化一下。
状态转移方程:
d p [ i ] [ j ] = d p [ i − 1 ] [ k ] + b i − ∣ a i − j ∣ dp[i][j]=dp[i-1][k]+b_i-|a_i-j| dp[i][j]=dp[i−1][k]+bi−∣ai−j∣… ( ∣ j − k ∣ < = ( t i − t i − 1 ) ∗ d ) (|j-k|<=(t_i-t_{i-1})*d) (∣j−k∣<=(ti−ti−1)∗d)
#include<bits/stdc++.h>
#define mp make_pair
#define se second
#define fi first
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, int> pli;
typedef pair<ll, ll> pll;
typedef long double ld;
const int N=5e5+10;
const int MAXN=20010;
const int INF=0x3f3f3f3f;
const ll INF64=0x3f3f3f3f3f3f3f3f;
const double eps=0.0000001;
const ll mod=1e9+7;
ll n,m,x,y,z,k,cnt,t,len;
ll a[N],b[N],ti[N];
ll dp[2][150005];///滚动数组优化
struct node
{
ll x,y;
}v[150005];
int