题解:P14508 猜数游戏 guess

目前暂无修正。

发现难以直接在原序列上做,考虑划分子结构,只需解决长度为 \(i\) 的找隐藏点问题。有两种可能,第一种是找 \([1,n]\) 中隐藏点,当前在 \(1\),第二种是当前在 \(n+1\)。由于行走规定开出的区间是 \([l,r)\),所以两种情况是对称的。

考虑解决 \([1,i]\) 中找点问题,令 \(f_i\) 表示其最小代价,从 \(1\) 出发,枚举走的长度 \(j\),最小费用 \(cost_j\),即可划分为:

\[f_i=\min_{j=1}^{i-1}\{\max(f_j,f_{i-j})+cost_j\} \]

答案即为 \(f_n\)。枚举状态 + 转移 \(O(n^2)\) 难以通过(吗?反正我没敢试),考虑缩小 \(j\) 上限,发现走多步可以拆分为若干个走一步,所以 \(j\) 只需要最大取到 \(V=\max a_i\)

如何计算 \(cost_j\)?一个错误的思路是,完全背包处理加的部分再处理减的部分。暴力上完整容积的背包,复杂度显然是不对的。完全背包的下标转移实质上就相当于最短路转移,而如果压缩这个完全背包,难以找到一个有效的顺序正确计算其值(其实真正有效顺序类似于堆优化,一定先找最小的更新别人)。

发现求取 \(cost_j\) 本质上是从 \(0\) 出发,向右跳到点 \(j\) 需要的最小费用。采用堆优化最短路,由于只需要走一段前缀,需要建出点 \([-n,n]\) 以便进行先减后加的操作,又根据 \(j\) 的上界只需建出 \([-V,V]\),每次 \(O(m)\) 访问所有可能边即可,总边数是 \(O(mV)\) 的。

总时间复杂度 \(O(T(nV+mV\log {mV}))\)

点击查看代码
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL,int> PII;
const int N=1e4+5,M=1e3+5;
const LL INF=1e16;
int n,m,mx;
LL cost[N*2],f[N];
struct Q{int a,b;}op[M];
priority_queue<PII,vector<PII>,greater<PII> >q;
inline void utov(int &u,int &v,int &w){
	if(cost[u+N]+w<cost[v+N])
		cost[v+N]=cost[u+N]+w,
		q.push(make_pair(cost[v+N],v));
}
void Dij(){
	for(int i=-mx;i<=mx;i++)
		cost[i+N]=INF;
	cost[N]=0;
	q.push(make_pair(0,0));
	while(!q.empty()){
		PII tp=q.top();q.pop();
		int u=tp.second;
		if(tp.first!=cost[u+N])continue;
		for(int i=1;i<=m;i++){
			if(u+op[i].a<=mx){
				int v=u+op[i].a;
				utov(u,v,op[i].b);
			}
			if(u-op[i].a>=-mx){
				int v=u-op[i].a;
				utov(u,v,op[i].b);
			}
		}
	}
}
int main(){
	//freopen("guess.in","r",stdin);
	//freopen("guess.out","w",stdout);
	int Cn,Tn;scanf("%d%d",&Cn,&Tn);
	while(Tn--){
		mx=0;
		scanf("%d%d",&n,&m);
		for(int i=0;i<=n;i++)
			f[i]=INF;
		f[1]=0;
		for(int i=1;i<=m;i++)
			scanf("%d",&op[i].a),
			mx=max(mx,op[i].a);
		for(int i=1;i<=m;i++)
			scanf("%d",&op[i].b);
		Dij();
		for(int i=2;i<=n;i++){
			for(int j=1;j<=mx&&j<=i-1;j++)
				f[i]=min(f[i],max(f[j],f[i-j])+cost[j+N]);
		}
		printf("%lld\n",f[n]<INF?f[n]:-1);
	}
	return 0;
}
posted @ 2025-11-15 13:31  TBSF_0207  阅读(67)  评论(1)    收藏  举报