HDU5945 Fxx and game(DP+单调队列优化)

本文介绍了一个名为Fxxandgame的问题,玩家需要通过特定操作将给定整数X减少到1,旨在寻找达到目标所需的最少步骤。文中提供了一种利用单调队列优化动态规划算法的有效解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Fxx and game

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


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=Xi(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(1T20) indicating the number of test cases.

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

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
wange2014   |   We have carefully selected several similar problems for you:   6216  6215  6214  6213  6212 
  哇哈哈哈哈这题上数学课的时候发现忘记把第一个数存入队列了(上课的时候没事干思忖了一下单调队列的原理还有单调队列和单调栈的用途 ),然后下课飞奔至姬房,顺带发现忘记压入后面的数了,反正一个下课就把这题搞好咯~ 不虚此行,撤!
 1 #include "bits/stdc++.h"
 2 using namespace std;
 3 typedef long long LL;
 4 const int MAX=1e6+5;
 5 int T,n,k,t;
 6 int dp[MAX];
 7 deque <int> q;
 8 int main(){
 9     freopen ("fxx.in","r",stdin);
10     freopen ("fxx.out","w",stdout);
11     int i,j;
12     scanf("%d",&T);
13     int an;
14     while (T--){
15         scanf("%d%d%d",&n,&k,&t);
16         if (t==0){
17             an=0;
18             while (n!=1){n/=k;an++;}
19             printf("%d\n",an);
20             continue;
21         }
22         if (k==0){
23             printf("%d\n",(n-2)/t+1);
24             continue;
25         }
26         dp[1]=0;
27         while (q.size()) q.pop_back();
28         q.push_back(1);
29         for (i=2;i<=n;i++){
30             dp[i]=999999999;
31             if (i%k==0) dp[i]=min(dp[i],dp[i/k]+1);
32             while (q.size() && (i-t)>q.front()) q.pop_front();
33             if (q.size()) dp[i]=min(dp[i],dp[q.front()]+1);
34             while (q.size() && dp[i]<dp[q.back()]) q.pop_back();
35             q.push_back(i);
36         }
37         printf("%d\n",dp[n]);
38     }
39     return 0;
40 }

 

转载于:https://www.cnblogs.com/keximeiruguo/p/7681668.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值