hdu 5945 Fxx and game(单调队列优化DP)

题目链接:hdu 5945 Fxx and game

题意:

让你从x走到1的位置,问你最小的步数,给你两种走的方式,1.如果k整除x,那么你可以从x走一步到k。2.你可以从x走到j,j+t<=x

题解:

看这个数据规模,多半要用O(N)的做法,比赛的时候我当时用的贪心,但这肯定是错的,最终FST了,当时不会单调队列。

我们设dp[i],表示走到i的最小步数,那么就有dp[i]=min{dp[i/k](k|i),dp[j]+1(j+t<=x)}。

对于第一项,我们直接判断一下就行了,对于第二项,我们可以用单调队列来优化。

 1 #include<bits/stdc++.h>
 2 #define F(i,a,b) for(int i=a;i<=b;++i)
 3 using namespace std;
 4 
 5 const int N=1e6+7;
 6 int x,k,_,t,dp[N],Q[N];
 7 
 8 int main()
 9 {
10     scanf("%d",&_);
11     while(_--)
12     {
13         scanf("%d%d%d",&x,&k,&t);
14         int head=1,tail=0;
15         dp[1]=0,Q[++tail]=1;
16         F(i,2,x)
17         {
18             while(head<tail&&Q[head]+t<i)head++;
19             dp[i]=dp[Q[head]]+1;
20             if(i%k==0)dp[i]=min(dp[i],dp[i/k]+1);
21             while(head<tail&&dp[Q[tail]]>dp[i])tail--;
22             Q[++tail]=i;
23         }
24         printf("%d
",dp[x]);
25     }
26     return 0;
27 }
View Code
原文地址:https://www.cnblogs.com/bin-gege/p/6165746.html