HDU 5945 Fxx and game 单调队列优化DP

本文分析了HDU 5945题目的解题思路,采用动态规划方法解决如何通过除以k和减去任意小于等于t的数使x变为0的问题。介绍了使用单调队列维护状态转移,实现O(X)的时间复杂度。

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

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5945

题意:数x,
1.如果x%k == 0 ,那么可以对x除以k
2.对x减去包括t以内的任意一个数
问多少步操作能使x变为0

dp[j] 表示 j最少能在多少步以内达到1
那么有转移公式
1.这里写图片描述
2.这里写图片描述
第一个转移方程可以用一个单调递增队列来维护
这样总的复杂度就是O(X)的了

代码:

#include <bits/stdc++.h>
#define sf scanf
#define pf printf

using namespace std;
const int maxn = 1000000 + 50;
int x,t,k,dp[maxn];
int q[maxn],qf,qt;
int main(){
    int T;sf("%d",&T);
    while(T--){
        sf("%d %d %d",&x,&k,&t);
        memset(dp,0x3f,sizeof dp);
        dp[1] = 0;
        qf = qt = 0;
        q[qt++] = 1;
        for(int i = 2;i <= x;++i){
            while(qf != qt && q[qf] < i - t) qf++;
            if(qf != qt) dp[i] = dp[q[qf]] + 1;
            if(i % k == 0) dp[i] = min(dp[i],dp[i / k] + 1);
            while(qf != qt && dp[q[qt - 1]] >= dp[i]) qt--;
            q[qt++] = i;
        }
        pf("%d\n",dp[x]);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值