Fxx and game
Accepts: 74
Submissions: 1857
Time Limit: 3000/1500 MS (Java/Others)
Memory Limit: 131072/65536 K (Java/Others)
问题描述
青年理论计算机科学家Fxx给的学生设计了一款数字游戏。 一开始你将会得到一个数X,每次游戏将给定两个参数k,t, 任意时刻你可以对你的数执行下面两个步骤之一: 1.X=X−i(1<=i<=t)。 2.若X为k的倍数,X=X/k。 现在Fxx想要你告诉他最少的运行步骤,使X变成1。
输入描述
第一行一个整数T(1≤T≤20)表示数据组数。 接下来T行,每行三个数X,k,t(0≤t≤106,1≤X,k≤106) 数据保证有解。
输出描述
输出共T行。
每行一个整数表示答案。
输入样例
2 9 2 1 11 3 3
输出样例
4 3
虽然还不是很懂,但是先发AC代码!
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#define mem(a,b) memset(a,b,sizeof(a))
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define ll long long
using namespace std;
const int maxn = 1e6 + 5;
int dp[maxn], f[maxn];
int main()
{
int T, x, k, t;
scanf("%d", &T);
while(T--)
{
scanf("%d%d%d", &x, &k, &t);
mem(dp, 63);
int head = 1, tail = 0;
dp[1] = 0;
f[++tail] = 1;
rep(i,2,x)
{
if(i % k == 0)
dp[i] = dp[i/k] + 1;
while(head <= tail && f[head] + t < i)
head++;
if(head <= tail)
dp[i] = min(dp[i], dp[f[head]] + 1);
f[++tail] = i;
while(head < tail && dp[f[tail-1]] > dp[f[tail]])
f[tail-1] = f[tail], tail--;
}
printf("%d\n", dp[x]);
}
return 0;
}