【HDU 5945】Fxx and game

博客提到某题目直接搜索不可行,可用动态规划(DP)解决。状态转移最多有t+1个,状态数有限,可通过单调队列维护前i - t个最值。当k能整除x时,还有特定的状态转移方程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.题目链接。一开始想直接搜索过了,但是发现似乎不得行。然后dp可做,因为上一状态向下一状态的转移最多只有t+1个

dp[i]=min(dp[i-1],dp[i-2]....dp[i-t])+1当k|x时,dp[i]=min(dp[i],dp[i/k]+1).所以这个状态数有限,单调队列维护一下前i-t个最值即可。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 10;
int dp[maxn];//dp[i]表示i走到1的最小的步数
int Q[maxn];
int main()
{

	int T;
	scanf("%d", &T);
	while (T--)
	{
		memset(Q, 0, sizeof(Q));
		memset(dp, 0, sizeof(dp));
		int X, k, t;
		scanf("%d%d%d", &X, &k, &t);
		if (t == 0)
		{
			int ans = 0;
			while (X != 1)
			{
				X /= k;
				ans++;
			}
			cout << ans << endl;
			continue;
		}
		if (k == 1)
		{
			int ans = 0;
			ans = X / t;
			if (X % t>1)ans++;
			cout << ans << endl;
			continue;
		}
		dp[1] = 0;
		int head =1,tail = 1;
		Q[1] = 1;
		for (int i = 2; i <= X; i++)
		{
			while (head <= tail && Q[head] < i - t)
				head++;
			dp[i] = dp[Q[head]] + 1;
			if (i % k == 0)
				dp[i] = min(dp[i], dp[i / k]+1);
			while ((head <= tail) && dp[i] <= dp[Q[tail]])
				tail--;
			Q[++tail] = i;
		}

		cout << dp[X] << endl;
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值