CF1131G Most Dangerous Shark

一、题目

点此看题

二、解法

考虑每个点的推倒状态只有向左倒和向右倒,然后我们又要把所有骨牌推倒,所以设计 \(dp[i]\) 表示推倒前 \(i\) 个骨牌的最小代价,假设我们会处理 \(l[i],r[i]\) 表示向左推倒骨牌 \(i\) 覆盖的左端点,向右推倒骨牌 \(i\) 覆盖的右端点,转移:

  • \(i\) 向左推倒:\(dp[i]=dp[j]+c[i] \ \ \ \ \ l[i]-1\leq j<i\)

  • \(j\) 向右推倒:\(dp[i]=dp[j-1]+c[j] \ \ \ \ \ j<i\leq r[j]\)

第一种转移其实只需要考虑 \(j=l[i]-1\) 时的转移即可,因为 \([l[i],i]\) 的骨牌 \(i\) 能推倒就不需要前面去管了。第二种转移看似需要线段树优化,做到 \(O(n)\) 我们需要观察性质。

不难发现每个骨牌的覆盖范围要么包含,要么相离,所以可以维护一个栈,每次新加入的点就放在栈顶,每次只需要考虑栈顶得覆盖范围够不够,不够直接弹出,然后维护一个栈的前缀最小值就可以转移了。

现在的问题是算 \(l[i],r[i]\),就说 \(l[i]\) 怎么算吧,还是维护一个栈,首先弹出没有用的点,也就是 \(i-h[i]\leq tp-h[tp]\),并且栈顶对于以后的元素也没有用了。然后我们考虑当前点能不能覆盖到栈顶,如果不能的话就直接用 \(i-h[i]+1\),如果可以的话就用 \(l[tp]\),不难发现他是最优的。

三、总结

考虑每个点的状态有哪些,然后 \(dp\),只要涉及了所有状态就可以。

\(dp\) 的线性优化可以考虑找性质,然后用单调数据结构维护该性质。

#include <cstdio>
#include <vector>
#include <iostream>
using namespace std;
const int M = 10000005;
const int N = 250005;
#define int long long
int read()
{
	int x=0,f=1;char c;
	while((c=getchar())<'0' || c>'9') {if(c=='-') f=-1;}
	while(c>='0' && c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
	return x*f;
}
int n,m,q,h[M],c[M],f[M],l[M],r[M],st[M],mn[M];
vector<int> a[N],b[N];
signed main()
{
	n=read();m=read();
	for(int i=1;i<=n;i++)
	{
		int k=read();
		for(int j=1;j<=k;j++) a[i].push_back(read());
		for(int j=1;j<=k;j++) b[i].push_back(read());
	}
	q=read();n=0;
	while(q--)
	{
		int id=read(),ml=read();
		for(int i=0;i<a[id].size();i++)
			h[++n]=a[id][i],c[n]=b[id][i]*ml;
	}
	int qr=0;
	for(int i=1;i<=n;i++)
	{
		while(qr && i-h[i]<=st[qr]-h[st[qr]]) qr--;//useless
		if(!qr || i-h[i]>=st[qr]) l[i]=max(i-h[i]+1,1ll);
		else l[i]=l[st[qr]];
		st[++qr]=i;
	}
	qr=0;
	for(int i=n;i>=1;i--)
	{
		while(qr && i+h[i]>=st[qr]+h[st[qr]]) qr--;
		if(!qr || i+h[i]<=st[qr]) r[i]=min(i+h[i]-1,m);
		else r[i]=r[st[qr]];
		st[++qr]=i;
	}
	qr=0;mn[0]=1e18;
	for(int i=1;i<=n;i++)
	{
		while(qr && r[st[qr]]==i-1) qr--;//illegal
		f[i]=f[l[i]-1]+c[i];
		if(qr) f[i]=min(f[i],mn[qr]);
		st[++qr]=i;mn[qr]=min(mn[qr-1],f[i-1]+c[i]);
	}
	printf("%lld\n",f[n]);
}
posted @ 2021-07-14 10:48  C202044zxy  阅读(172)  评论(0编辑  收藏  举报