题目大意:一开始你将会得到一个数 X(1≤X≤106) ,每次游戏将给定两个参数 k,t(1≤k,t≤106) , 任意时刻你可以对你的数执行下面两个步骤之一:
1. X=X−i(1≤i≤t) 。
2.若
X
为
保证有解,求X变成1的最小步数。
题解:容易想到一个dp,
dp[i]
表示数字
i
需要的最少步数。那么转移为
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1000010;
int dp[maxn];
int q[maxn];
int id[maxn];
int f,r;
int main(){
int T,x,k,t;
scanf("%d",&T);
while(T--){
scanf("%d%d%d",&x,&k,&t);
f = r = 0;
dp[1] = 0;
id[r] = 1;
q[r++] = dp[1];
for(int i = 2;i <= x;i++){
while(f<r&&id[f]+t<i) f++;
int v = q[f];
if(f == r) v = maxn;
dp[i] = v+1;
dp[i] = min(dp[i],(i%k==0?dp[i/k]:maxn)+1);
while(f<r && q[r-1]>= dp[i]) r--;
id[r] = i;
q[r++] = dp[i];
}
printf("%d\n",dp[x]);
}
return 0;
}