【23.33%】【hdu 5945】Fxx and game

来源:互联网 发布:教父刀数据 编辑:程序博客网 时间:2024/05/29 04:17

Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 360 Accepted Submission(s): 84

Problem Description
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

【题解】

f[i] = min(f[i],f[i/k]+1);
f[i] = min(f[i],f[i-t..i-1]+1);
第二行那个转移可用一个单调队列优化;
因为f[i+1]>=f[i];
dl的最左边维护的是i-t..i-1这个区间内f值最小的点的下标;然后往右f值依次递增;
如果新加入的点i,f[i]小于这个dl最右边x对应值f[x],则把x挤掉(那些被挤掉的元素是肯定没有用了的,如果到了某个时刻f[i]被挤掉了,因为i>x,则x肯定也要被挤掉),重复上述步骤;
就能维护一个单调队列;
有点厉害.

#include <cstdio>#include <cmath>#include <set>#include <map>#include <iostream>#include <algorithm>#include <cstring>#include <queue>#include <vector>#include <stack>#include <string>#define lson L,m,rt<<1#define rson m+1,R,rt<<1|1#define LL long longusing namespace std;const int MAXN = 2e6;const int dx[5] = {0,1,-1,0,0};const int dy[5] = {0,0,0,-1,1};const double pi = acos(-1.0);const int INF = 0x3f3f3f3f;int x,k,t,l,r;int f[MAXN],dl[MAXN];void input_LL(LL &r){    r = 0;    char t = getchar();    while (!isdigit(t)) t = getchar();    LL sign = 1;    if (t == '-')sign = -1;    while (!isdigit(t)) t = getchar();    while (isdigit(t)) r = r * 10 + t - '0', t = getchar();    r = r*sign;}void input_int(int &r){    r = 0;    char t = getchar();    while (!isdigit(t)) t = getchar();    int sign = 1;    if (t == '-')sign = -1;    while (!isdigit(t)) t = getchar();    while (isdigit(t)) r = r * 10 + t - '0', t = getchar();    r = r*sign;}int main(){    //freopen("F:\\rush.txt", "r", stdin);    int T;    input_int(T);    while (T--)    {        memset(f,INF,sizeof(f));        input_int(x);input_int(k);input_int(t);        l = 1;r = 1;dl[r] = 1;        f[1] = 0;        for (int i = 2;i <= x;i++)        {            while (l<=r && dl[l]<i-t)l++;            if ((i%k)==0)                f[i] = min(f[i],f[i/k]+1);            if (l <=r)                f[i] = min(f[i],f[dl[l]]+1);            while (l<=r && f[i]<f[dl[r]]) r--;            dl[++r] = i;        }        printf("%d\n",f[x]);    }    return 0;}
0 0
原创粉丝点击