hdu 5945 Fxx and game

青年理论计算机科学家Fxx给的学生设计了一款数字游戏。

一开始你将会得到一个数X,每次游戏将给定两个参数x,k,t, 任意时刻你可以对你的数执行下面两个步骤之一:

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

2.若X为k的倍数,X=X/k。

现在Fxx想要你告诉他最少的运行步骤,使X变成1。
 

设f[x]为x的最小变为1步数

initialize: f[1]=0

equation: f[x]=min{f[x-i](i<=t),f[x/k](if x%k==0)} (x:1~x)

对于求min{f[x-i](i<=t)} 使用单调队列维护区间最小f[x-i]

#include <iostream>
#include <cstring>
#include <cmath>
#include <deque>
using namespace std;
const int N=1e6+10;
int f[N],k,t;
deque<int>mn;
int dfs(int x)
{
    f[1] = 0;
    mn.clear();
    mn.push_back(1);
    int j = 1;
    for(int i=2;i<=x;i++)
    {
        if(i%k==0) f[i]=min(f[i],f[i/k]+1);
        while(!mn.empty() and i-mn.front() > t) mn.pop_front();
        if(!mn.empty() and i-mn.front() <= t)
        {
            f[i]=min(f[i],f[mn.front()]+1);
        }
        while(!mn.empty() and f[mn.back()] >= f[i]) mn.pop_back();
        mn.push_back(i);
    }
    return f[x];
}
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        memset(f,0x3f,sizeof(f));
        int x;
        cin>>x>>k>>t;
        if(k>1)
        cout<<dfs(x)<<endl;
        else cout<<int(ceil(double(x-1)/t))<<endl;
    }
    return 0;
}
View Code

 

 
posted @ 2016-12-05 20:26  江南何采莲  阅读(264)  评论(0编辑  收藏  举报