HUD_5945 Fxx and game(DP加上单调队列优化)

Young theoretical computer scientist Fxx designed a game for his students.

In each game, you will get three integers X,k,t.In each step, you can only do one of the following moves:

1.X=X−i(0<=i<=t).

2.if k|X,X=X/k.

Now Fxx wants you to tell him the minimum steps to make X become 1.

Input
In the first line, there is an integer T(1≤T≤20) indicating the number of test cases.

As for the following T lines, each line contains three integers X,k,t(0≤t≤106,1≤X,k≤106)

For each text case,we assure that it’s possible to make X become 1。

Output
For each test case, output the answer.

Sample Input
2
9 2 1
11 3 3

Sample Output
4
3

Source
BestCoder Round #89

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <string>
#include <set>
#include <cmath>
#include <deque>
using namespace std;
typedef long long ll;
const int maxn = 1e6+7;
const int maxn2= 47711;
const int inf =0x3f3f3f3f;
const int mod = 10007;
int n,k,t;
int dp[maxn];
int id[maxn],ip[maxn];
int main()
{
    int m;cin>>m;
    while(m--){
        cin>>n>>k>>t;
        memset(dp,inf,sizeof(dp));dp[1]=0;
        int rear=-1,front=0;
        for(int i=1;i<=n;i++){
            if(i%k==0) dp[i]=min(dp[i],dp[i/k]+1);
            if(rear+1==front){
                id[++rear]=dp[i];ip[rear]=i;
            }else{
                while(dp[i]<id[rear]&&rear>=front) rear--;
                id[++rear]=dp[i];ip[rear]=i;
                if(i-ip[front]==t+1) ++front;
            }
            dp[i]=min(dp[i],dp[ip[front]]+1);
        }
        printf("%d\n",dp[n]);
    }
    return 0;
}
发布了35 篇原创文章 · 获赞 25 · 访问量 815

猜你喜欢

转载自blog.csdn.net/qq_43816599/article/details/103940620