Fxx and game
Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)Total Submission(s): 816 Accepted Submission(s): 201
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
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=5945
中文链接:http://bestcoder.hdu.edu.cn/contests/contest_chineseproblem.php?cid=730&pid=1002
题意:
一开始你将会得到一个数X,每次游戏将给定两个参数k,t, 任意时刻你可以对你的数执行下面两个步骤之一: 1.X=X−i(1<=i<=t)。 2.若X为k的倍数,X=X/k。 现在Fxx想要你告诉他最少的运行步骤,使X变成1。
此题也有人用DFS,BFS解决的,但出题人的题解是单调队列+DP
设Fi表示将i变为1的最少步骤,如果k∣i,Fi=min{Fj,Fki},否则Fi=min{Fj},其中i−t≤j≤i−1。
用单调队列维护一下就好了。
时间复杂度O(n)。
单调队列的介绍: http://blog.csdn.net/dgq8211/article/details/7430726http://blog.csdn.net/yjf3151731373/article/details/52971482
参考博客:http://blog.csdn.net/acmore_xiong/article/details/52969485
#include <bits/stdc++.h>
using namespace std;
int T, X, k, t;
const int MAXN = 1e6 + 5;
const int INF = 0x3f3f3f3f;
queue<int> Q;
int dp[MAXN];
int main()
{
scanf("%d", &T);
while(T --)
{
scanf("%d %d %d", &X, &k, &t);
memset(dp, 0x3f, sizeof(dp));
while(!Q.empty()) Q.pop();
dp[1] = 0;
Q.push(1);
for(int z = 1; z <= X; z++)
{
while(!Q.empty() && Q.front() < z - t)
Q.pop();
if(!Q.empty())
dp[z] = min(dp[z], dp[Q.front()] + 1);
if(z % k == 0)
dp[z] = min(dp[z], dp[z / k] + 1);
while(!Q.empty() && dp[Q.front()] >= dp[z])
Q.pop();
Q.push(z);
}
printf("%d\n", dp[X]);
}
return 0;
}
尊重原创,转载请注明出处:http://blog.csdn.net/hurmishine