Fxx and game
Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)Total Submission(s): 347 Accepted Submission(s): 78
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.
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。
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
Recommend
题解:dp+单调队列
f[i]表示到达数字i最少需要多少步 ,初始值f[1]=0
if (i%k==0) f[i]=min(f[i],f[i/k]+1)
f[i]=min(f[i],f[j]+1) i-t<=j<=i-1
然后用单调队列维护,使队列中的元素单调不降,并保证队列中元素的位置不小于i-t。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define N 1000003
using namespace std;
int n,k,t,x,p[N],pos[N],f[N];
int main()
{
freopen("a.in","r",stdin);
freopen("std.out","w",stdout);
scanf("%d",&n);
for (int i=1;i<=n;i++){
scanf("%d%d%d",&x,&k,&t);
memset(f,127,sizeof(f));
f[1]=0; int head=1; int tail=1;
p[tail]=f[1]; pos[tail]=1;
for (int i=2;i<=x;i++) {
while(tail>head&&pos[head]<max(1,i-t)) head++;
f[i]=min(f[i],p[head]+1);
if (i%k==0) f[i]=min(f[i],f[i/k]+1);
while (tail>=head&&f[i]<=p[tail]) tail--;
++tail; p[tail]=f[i]; pos[tail]=i;
}
printf("%d\n",f[x]);
}
}