【HDU 5945】Fxx and game(DP+单调队列)

来源:互联网 发布:java教程菜鸟教程 编辑:程序博客网 时间:2024/06/07 14:11

【HDU 5945】Fxx and game(DP+单调队列)

啊啊啊啊啊啊啊。。。BC第二题就这么难了……好菜啊……这游戏没法玩了啊……。。。

膜一下队伍主力 金QAQ巨。。。现两号BC金。。Orz……@a1s4z5

顺吐槽一发……大家BC页面会卡么……宿舍进BC卡得要死……具体卡成什么样子……校园网进不去热点也卡的要命,耐心等待题面一帧帧 浮现 出来……然后已经被甩出去好几条街了……然后……咦……这A题坑点很迷啊,Hack肯定很爽啊,耐心等待页面 一条条 出现后……双击room里一人的A题……我选择放弃。。。。

从此BC成路人……

言归正传,这题还是很好的……即使因此分掉了一大截……摔。。

具体的:给出x,t,k,要将数字x变成1。操作有二:
1.把数字x变成数字y(0 <= x-y <= t),消耗一步。
2.x->x/k(if x%k == 0),消耗一步。

一开始的想法很犀利……定义dp[i]为从x变成i的最少步数,那么答案其实是min(dp[i])1<=i<k,因为到k的话肯定会/k变成1,其实就是dp[1],所以只考虑1~k-1。

然后对于i(1 <= i < k),找到最大的y,满足y%k == 0 && y/k == i && y <= x
然后计算从x变成y,然后从y变成i,从i变成1。前后除t即可,中间就有点暴力了。。然后就爆炸了……然后刚才发现有地方写搓了。。然后改了后测了一些数据发现这种贪心是有问题的……然后还是爆炸了……

还是规规矩矩的做法吧,dp[i]表示i变成1的最少步数。
那么如果i%k != 0 那么dp[i] = min(dp[j])+1(0 <= i-j <= t)
如果i%k == 0,最小值里再取个dp[i/k]。

暴力的话会超时,维护一个跟i距离t内的单调队列,队列里的数值从左到右单调递增,右边入队左边取值即为t内最少步数。

代码如下:

#include <iostream>#include <cmath>#include <vector>#include <cstdlib>#include <cstdio>#include <climits>#include <ctime>#include <cstring>#include <queue>#include <stack>#include <list>#include <algorithm>#include <map>#include <set>#define LL long long#define Pr pair<int,int>#define fread(ch) freopen(ch,"r",stdin)#define fwrite(ch) freopen(ch,"w",stdout)using namespace std;const int INF = 0x3f3f3f3f;const int mod = 1e9+7;const double eps = 1e-8;const int maxn = 1123456;int s[maxn];int dp[maxn];int main(){    //fread("");    //fwrite("");    int t,T,l,r,x,k;    scanf("%d",&T);    while(T--)    {        scanf("%d%d%d",&x,&k,&t);        dp[1] = 0;        l = 0;        r = -1;        s[++r] = 1;        for(int i = 2; i <= x; ++i)        {            if(i%k == 0 && k != 1) dp[i] = dp[i/k]+1;            if(l <= r)             {                if(i%k == 0 && k != 1) dp[i] = min(dp[i],dp[s[l]]+1);                else dp[i] =dp[s[l]]+1;            }            while(l <= r && dp[i] <= dp[s[r]])                r--;            s[++r] = i;            while(l <= r && i-s[l] >= t) ++l;        }        printf("%d\n",dp[x]);    }    return 0;}
0 0