题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5945
题意:数x,
1.如果x%k == 0 ,那么可以对x除以k
2.对x减去包括t以内的任意一个数
问多少步操作能使x变为0
dp[j] 表示 j最少能在多少步以内达到1
那么有转移公式
1.
2.
第一个转移方程可以用一个单调递增队列来维护
这样总的复杂度就是O(X)的了
代码:
#include <bits/stdc++.h>
#define sf scanf
#define pf printf
using namespace std;
const int maxn = 1000000 + 50;
int x,t,k,dp[maxn];
int q[maxn],qf,qt;
int main(){
int T;sf("%d",&T);
while(T--){
sf("%d %d %d",&x,&k,&t);
memset(dp,0x3f,sizeof dp);
dp[1] = 0;
qf = qt = 0;
q[qt++] = 1;
for(int i = 2;i <= x;++i){
while(qf != qt && q[qf] < i - t) qf++;
if(qf != qt) dp[i] = dp[q[qf]] + 1;
if(i % k == 0) dp[i] = min(dp[i],dp[i / k] + 1);
while(qf != qt && dp[q[qt - 1]] >= dp[i]) qt--;
q[qt++] = i;
}
pf("%d\n",dp[x]);
}
}