cdoj Dividing Numbers 乱搞记忆化搜索
//真tm是乱搞 但是(乱搞的)思想很重要
解:大概就是记忆化搜索,但是原数据范围太大,不可能记下所有的情况的答案,于是我们就在记下小范围内的答案,当dfs落入这个记忆范围后,就不进一步搜索,直接返回记下来的答案,这样就起到了优化的效果,但是并不知道这种复杂度是怎么算的。然而我们由大到小排序,使得状态总可以很快地落入记忆化的范围。
dfs(n,now)代表[1..n]内不会被a[now]...a[k-1]整除的数有多少,那么答案就是dfs(n,0)。
转移关系如下:dfs(n,now)=dfs(n,now+1)-dfs(n/a[i],now+1)
之所以要-dfs(n/a[i],now+1)是为了避免一个数被重复减多次,能被整除的数整除后按大小排列一定是1,2,3,...,n/a[i],如果能被后面的数整除,就将其减去,也就是减dfs(n/a[i],now+1).
/*
某学长的讲解:
假设N比较小,可以这样做。dp[i][j]表示前i个素数,范围在[1,j]里的答案。那么,方程转移dp[i][j]=dp[i-1][j]+dp[i-1][j/p[i]]。(具体为啥仔细想想素数的性质,或者按照分解素数方法来想)
N很大,怎么办。当N<10万,20万,30万可以直接dp做。当N很大的时候,注意到j/p[i],是log级别的,情况数并不会很多。所以可以设一个M,比如M=20万,当j<=M的时候,记忆化,O(1)查询,当j>M的时候,dfs搜索。
这题不好分析复杂度。可以发现,P数组里元素顺序是不影响答案的,我们可以把P从小到大排序,这样j/p[i]中的p[i]会更大,搜索起来更快。(当然,这只是小优化)。
不会写的话看代码。
*/
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<vector>
#include<map>
#include<stack>
#include<string> using namespace std; const int MAXN=; long long n;
int k;
int a[];
long long f[MAXN][]; bool cmp(int a,int b){
return a>b;
} long long dfs(long long n,int now){
if (now>=k || n==) return n;
if (n<MAXN && f[n][now]>=) return f[n][now];
long long tmp=dfs(n,now+)-dfs(n/a[now],now+);
if (n<MAXN) f[n][now]=tmp;
return tmp;
} int main(){
scanf("%lld%d",&n,&k);
for (int i=;i<MAXN;i++){
for (int j=;j<k;j++){
f[i][j]=-;
}
}
for (int i=;i<k;i++) scanf("%d",&a[i]);
sort(a,a+k,cmp);
printf("%lld\n",dfs(n,)); //printf("I64d printed\n");
return ;
}
/*
20 3
2 3 5 50 2
15 8
*/
cdoj Dividing Numbers 乱搞记忆化搜索的更多相关文章
- CF1028G Guess the Numbers 构造、记忆化搜索
传送门 考虑如果我们当前可以询问\(x\)个数,还剩下\(q\)次询问机会,我们要怎么构造询问方式? 肯定会这么考虑: 找到一个尽可能大的\(P\)满足\([x,P]\)能在每一次能询问\(x\)个数 ...
- Codeforces 374 C. Travelling Salesman and Special Numbers (dfs、记忆化搜索)
题目链接:Travelling Salesman and Special Numbers 题意: 给了一个n×m的图,图里面有'N','I','M','A'四种字符.问图中能构成NIMA这种序列最大个 ...
- POJ 3252 Round Numbers(数位dp&记忆化搜索)
题目链接:[kuangbin带你飞]专题十五 数位DP E - Round Numbers 题意 给定区间.求转化为二进制后当中0比1多或相等的数字的个数. 思路 将数字转化为二进制进行数位dp,由于 ...
- 牛客假日团队赛5 F 随机数 BZOJ 1662: [Usaco2006 Nov]Round Numbers 圆环数 (dfs记忆化搜索的数位DP)
链接:https://ac.nowcoder.com/acm/contest/984/F 来源:牛客网 随机数 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言6 ...
- UVA 825 Walking on the Safe Side(记忆化搜索)
Walking on the Safe Side Square City is a very easy place for people to walk around. The two-way ...
- tyvj 1004 滑雪 记忆化搜索
滑雪 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.tyvj.cn/p/1004 Description trs喜欢滑雪.他来 ...
- hdu3555 Bomb (记忆化搜索 数位DP)
http://acm.hdu.edu.cn/showproblem.php?pid=3555 Bomb Time Limit: 2000/1000 MS (Java/Others) Memory ...
- UVALive 6470 Chomp --记忆化搜索
题意:给一个只有三行的方块阵(横向最多100个),然后p,q,r分别代表第1,2,3层的方格数,两人轮流去掉一个格子,此时这个格子的右上方都会被去掉,面临只剩最左下角的一个格子的状态的人输,问先手能否 ...
- CodeForces 173C Spiral Maximum 记忆化搜索 滚动数组优化
Spiral Maximum 题目连接: http://codeforces.com/problemset/problem/173/C Description Let's consider a k × ...
随机推荐
- 经典面试题(二)附答案 算法+数据结构+代码 微软Microsoft、谷歌Google、百度、腾讯
1.正整数序列Q中的每个元素都至少能被正整数a和b中的一个整除,现给定a和b,需要计算出Q中的前几项, 例如,当a=3,b=5,N=6时,序列为3,5,6,9,10,12 (1).设计一个函数void ...
- QTableWidget嵌入QpushButton后定位QpushButton
问题: 有时候会遇到这样的情况,在QTableWidget中我们需要嵌入一个QpushButton按钮,但是如何确定是哪个Button按下的呢? 解决: 一般地,一个按钮按下后会连接到一槽函数,那么在 ...
- Oracle EBS-SQL (PO-15):检查不能审批的PO.sql
SELECT PHA.SEGMENT1, PHA.WF_ITEM_KEY, PHA.* FROM PO.PO_HEADERS_ALL PHA WHERE PHA.AUTHORIZATION_STA ...
- Jar
http://docs.oracle.com/javase/6/docs/technotes/guides/jar/jar.html#Intro http://docs.oracle.com/java ...
- Unix/Linux环境C编程入门教程(27) 内存那些事儿
calloc() free() getpagesize() malloc() mmap() munmap()函数介绍 calloc(配置内存空间) 相关函数 malloc,free,realloc,b ...
- SQLCLUSTER sql数据库监测工具
SQLCLUSTER sql数据库监测工具
- [Leetcode][Python]43: Multiply Strings
# -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 43: Multiply Stringshttps://leetcode.co ...
- 【POJ 3009 Curling2.0 迷宫寻径 DFS】
http://poj.org/problem?id=3009 模拟冰壶的移动,给出到达终点的最少投掷次数(不可达时为-1). 具体移动规则如下: 每次选四个方向之一,沿此方向一直前进,直到撞到bloc ...
- 匿名方法和Lambda表达式
匿名方法本质上是一传递给委托的代码块,是使用委托的另一种方法. 规则: 1.匿名方法中不能使用跳转语句跳至次匿名方法的外部,反之亦然:匿名方法外部的跳转语句也不能跳转到匿名方法的内部: 2.在匿名方法 ...
- Unity doesn't load, no Launcher, no Dash appears
1. 重新安装 ubuntu-desktop不起作用. Enter the following commands:- Ctrl+Alt+F1 login there by user name and ...