//真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).

/*

某学长的讲解:

 给K个两两互素的数,问[1,N]中有多少个数不被K个数里任何一个数整除。

假设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 乱搞记忆化搜索的更多相关文章

  1. CF1028G Guess the Numbers 构造、记忆化搜索

    传送门 考虑如果我们当前可以询问\(x\)个数,还剩下\(q\)次询问机会,我们要怎么构造询问方式? 肯定会这么考虑: 找到一个尽可能大的\(P\)满足\([x,P]\)能在每一次能询问\(x\)个数 ...

  2. Codeforces 374 C. Travelling Salesman and Special Numbers (dfs、记忆化搜索)

    题目链接:Travelling Salesman and Special Numbers 题意: 给了一个n×m的图,图里面有'N','I','M','A'四种字符.问图中能构成NIMA这种序列最大个 ...

  3. POJ 3252 Round Numbers(数位dp&amp;记忆化搜索)

    题目链接:[kuangbin带你飞]专题十五 数位DP E - Round Numbers 题意 给定区间.求转化为二进制后当中0比1多或相等的数字的个数. 思路 将数字转化为二进制进行数位dp,由于 ...

  4. 牛客假日团队赛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 ...

  5. 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 ...

  6. tyvj 1004 滑雪 记忆化搜索

    滑雪 Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://www.tyvj.cn/p/1004 Description     trs喜欢滑雪.他来 ...

  7. hdu3555 Bomb (记忆化搜索 数位DP)

    http://acm.hdu.edu.cn/showproblem.php?pid=3555 Bomb Time Limit: 2000/1000 MS (Java/Others)    Memory ...

  8. UVALive 6470 Chomp --记忆化搜索

    题意:给一个只有三行的方块阵(横向最多100个),然后p,q,r分别代表第1,2,3层的方格数,两人轮流去掉一个格子,此时这个格子的右上方都会被去掉,面临只剩最左下角的一个格子的状态的人输,问先手能否 ...

  9. CodeForces 173C Spiral Maximum 记忆化搜索 滚动数组优化

    Spiral Maximum 题目连接: http://codeforces.com/problemset/problem/173/C Description Let's consider a k × ...

随机推荐

  1. FFMPEG图片转视频

    1.分离视频音频流 ffmpeg -i input_file -vcodec copy -an output_file_video //分离视频流 ffmpeg -i input_file -acod ...

  2. codeforces 519C.. A and B and Team Training

    C. A and B and Team Training time limit per test 1 second memory limit per test 256 megabytes input ...

  3. 【测试技术】ant中的for循环用法

    有的时候,我们希望ant中也能类似脚本语言一样进行for循环,以实现一些重复性工作.由于ant核心包并未提供此功能,所以需要下载一个扩展包扔到ant的lib目录下去.详细步骤如下: 1.下载核心包:a ...

  4. MFC 操作控件数据

    在MFC中有多种获取控件数据的方法 1.GetWindowText()和SetWindowText()函数   ],ch2[],ch3[]; GetDlgItem(IDC_EDIT1)->Get ...

  5. VS2012编译Snmp++ v3.2.25

    VS2012编译Snmp++ v3.2.25跟用VC6/VC2010等编译方法区别不大. 网上和教程上盛传的方式是把snmp++的cpp源文件和头文件都加到工程里,再编译.我觉得添加所有头文件到工程里 ...

  6. Bag of Words(BOW)模型

    原文来自:http://www.yuanyong.org/blog/cv/bow-mode 重复造轮子并不是完全没有意义的. 这几天忙里偷闲看了一些关于BOW模型的知识,虽然自己做图像检索到目前为止并 ...

  7. Xcode8 注释快捷键无效, 解决方案

    这个是因为苹果解决xcode ghost.把插件屏蔽了.解决方法命令运行: sudo /usr/libexec/xpccachectl 然后必须重启电脑后生效    

  8. lamda表达式学习

    lamda表达式 “Lambda 表达式”是一个匿名函数,它可以包含表达式和语句,并且可用于创建委托或表达式目录树类型. 格式:( 形参列表 ) => { 函数体 } 所有 Lambda 表达式 ...

  9. http头部信息研究

    1. Accept:告诉WEB服务器自己接受什么介质类型,*/* 表示任何类型,type/* 表示该类型下的所有子类型,type/sub-type. 2. Accept-Charset: 浏览器申明自 ...

  10. Android环境开发搭建

    今天第一次接触安卓,从开发环境的配置到程序的运行,足足搞了一天,也没有整出来. 1.安装JDK 在JDK官网上下载了最新的JDK,安装成功后进行环境的配置.JAVA_HOME:C:\Program F ...