HDU 5945 题解(DP)(单调队列)
题面:
Fxx and game
Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 2264 Accepted Submission(s): 600
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.
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。
Output
For each test case, output the answer.
Sample Input
2
9 2 1
11 3 3
Sample Output
4
3
分析:
此题可用dp求解
分解子问题:我们设dp[i]dp[i]表示i变为1需要的方法数
因为dp[i]可由dp[i/k]dp[i/k], dp[i−j](0<=j<=t)dp[i−j](0<=j<=t)转移过来
我们可以写出状态转移方程:
边界条件:dp[1]=0
时间复杂度: O(xt)O(xt)
但是该方法时间复杂度过高,必须要优化
单调队列的条件是:首先队列的值保持单调,维护答案一直在队首,然后队列里面的时间表现单调性,还有就是弹掉的东西一定没有新入队的优
维护一个dp[i]从队尾到队头递增的队列
因此我们每次算好dp[i]的时候把队尾中dp值小于等于dp[i]的都出队(队列里面的都是下标比i大的,值又没i优,是无用的)
dp[i]=min(dp[q[head]],dp[i/k])+1dp[i]=min(dp[q[head]],dp[i/k])+1
最后在队头弹出不满足条件的值
代码:
#include<iostream>
#include<cstring>
#define maxn 1000020
using namespace std;
int c,x,k,t;
int dp[maxn],q[maxn];
int head,tail;
int main() {
cin>>c;
while(c--) {
cin>>x>>k>>t;
int ans=0;
if(t==0) { //特判
while(x!=1) {
x/=k;
ans++;
}
}else if(k==0) {
if((x-1)%t==0) ans=(x-1)/t;
else ans=(x-1)/t+1;
} else {
head=0,tail=1;
memset(q,0,sizeof(q));
memset(dp,0x7f,sizeof(dp));
dp[1]=0;
q[head]=1;
for(int i=2; i<=x; i++) {
while(i-q[head]>t&&head<tail) head++;//单调队列优化
dp[i]=dp[q[head]]+1;
if(i%k==0) dp[i]=min(dp[i],dp[i/k]+1);
while(dp[q[tail]]>dp[i]&&head<tail) tail--;
q[++tail]=i;
}
ans=dp[x];
}
cout<<ans<<endl;
}
}
HDU 5945 题解(DP)(单调队列)的更多相关文章
- HDU 5945 维护一个单调队列 dp
Fxx and game Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)Tot ...
- HDU 3401 Trade dp+单调队列优化
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3401 Trade Time Limit: 2000/1000 MS (Java/Others)Mem ...
- HDU - 3415(DP + 单调队列)
链接:HDU - 3415 题意:给出一个包含 n 个数的环,求满足长度大于 0 小于等于 k 的最大区间和. 题解:将数组加倍,形成环.求一个前缀和sum.枚举每一个sum[i],以 i 结尾的最大 ...
- hdu 4123 树形DP+单调队列
http://acm.hust.edu.cn/vjudge/problem/25790 这题基本同poj 3162 要注意mx,mx2,vx,vx2每次都要初始化 #include <iostr ...
- [poj3017] Cut the Sequence (DP + 单调队列优化 + 平衡树优化)
DP + 单调队列优化 + 平衡树 好题 Description Given an integer sequence { an } of length N, you are to cut the se ...
- DP+单调队列 codevs 1748 瑰丽华尔兹(还不是很懂具体的代码实现)
codevs 1748 瑰丽华尔兹 2005年NOI全国竞赛 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题解 题目描述 Descripti ...
- (noip模拟二十一)【BZOJ2500】幸福的道路-树形DP+单调队列
Description 小T与小L终于决定走在一起,他们不想浪费在一起的每一分每一秒,所以他们决定每天早上一同晨练来享受在一起的时光. 他们画出了晨练路线的草图,眼尖的小T发现可以用树来描绘这个草图. ...
- 习题:烽火传递(DP+单调队列)
烽火传递[题目描述]烽火台又称烽燧,是重要的防御设施,一般建在险要处或交通要道上.一旦有敌情发生,白天燃烧柴草,通过浓烟表达信息:夜晚燃烧干柴,以火光传递军情.在某两座城市之间有n个烽火台,每个烽火台 ...
- 3622 假期(DP+单调队列优化)
3622 假期 时间限制: 1 s 空间限制: 64000 KB 题目等级 : 黄金 Gold 题目描述 Description 经过几个月辛勤的工作,FJ决定让奶牛放假.假期可以在1-N天内任意选择 ...
随机推荐
- 生成keystore
Android平台打包发布apk应用,需要使用数字证书(.keystore文件)进行签名,用于表明开发者身份,可以使用JRE环境中的keytool命令生成.以下是windows平台生成证书的方法: 安 ...
- 前端之JavaScript:JS之DOM对象二
继续JS之DOM对象二 前面在JS之DOM中我们知道了属性操作,下面我们来了解一下节点操作.很重要!! 一.节点操作 创建节点:var ele_a = document.createElement(' ...
- 自学semantic UI个人博客首页模板
以下是代码 <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <m ...
- SparkConf源码解读
------------恢复内容开始------------ 1.主要功能:SparkConf是Spark的配置类,配置spark的application的应用程序,使用(key,value)来进行存 ...
- 利用雅虎ycsb对cassandra做性能测试
准备: 环境: 两台虚拟机:ip:192.168.138.128/129;配置:2核4G: 版本:apache-cassandra-3.10 ycsb-cassandra-binding-0.1 ...
- echart-如何画自定义的图形,三角形为例
- table的td设置1px的方法,亲测有效
第一种方法: 1.将table的属性设置为:BORDER=0 .cellspacing=1 : 2.设置table的背景色为即你要设置的table的边框颜色: 3.设置所有td背景色为#ffffff白 ...
- [BZOJ3527][ZJOI2014]力:FFT
分析 整理得下式: \[E_i=\sum_{j<i}{\frac{q_i}{(i-j)^2}}-\sum_{j>i}{\frac{q_i}{(i-j)^2}}\] 假设\(n=5\),考虑 ...
- 《SQL Server 2012 T-SQL基础》读书笔记 - 5.表表达式
Chapter 5 Table Expressions 一个表表达式(table expression)是一个命名的查询表达式,代表一个有效的关系表.SQL Server包括4种表表达式:派生表(de ...
- 用shell和python实现数组的一个例子
目标是把字符串中的值等分为几段,取每段固定位置的值 shell脚本 #!/bin/bash ele="1 2 3 4 5 6" n= array1=() for x in $ele ...