http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4834

从点1出发,假设现在在i,点数为sta,则下一步的点数必然不能是sta的因数,所以不会形成环,只需从1直接走,走到n即可.

但是如果这样的话时空复杂度就都是nk,明显不满足题意,而这个时候我们可以想到,每个状态都必然是k的约数,(点数不是k的约数的节点不在路上,可以无视),而约数的个数也就k^0.5个,可以直接用map映射,这样时空复杂度都是n*k^0.5,可以解出答案.

一开始直接用dfs,结果TLE了.

#include <cstdio>
#include <cstring>
#include <map>
using namespace std;
const int maxn = 2001;
const int maxm = 2e4+4;
const int mod = 1000000007;
const int maxk = 1e6+6;
int n,m,k;
int p[maxn];
typedef long long ll;
map<int ,int >id;
ll dp[maxn][maxn];
int first[maxn];
struct edge{
int nxt,t;
}e[maxm];
void addedge(int f,int t,int ind){
e[ind].nxt = first[f];
e[ind].t = t;
first[f] = ind;
}
int bit[30],num;
void apart(int k){
for(int i=2;i*i<=k;i++){
while(k%i==0){
bit[num++]=i;
k/=i;
}
}
if(k>1)bit[num++]=k;
}
ll gcd(ll a,ll b){
if(b==0)return a;
return gcd(b,a%b);
}
ll lcm(ll a,ll b){
return a*b/gcd(a,b);
}
bool vis[maxn];
int cnt;
ll dfs(int s,int sav){
if(id[sav]!=0&&dp[s][id[sav]]!=0)return dp[s][id[sav]];
if(s==n)return sav==k?1:0;
vis[s]=true;
if(id[sav]==0)id[sav]=++cnt;
for(int pe=first[s];pe!=-1;pe=e[pe].nxt){
int t=e[pe].t;
ll lcmnum=lcm(p[t],sav);
if(vis[t]||lcmnum==sav||lcmnum>k)continue;
dp[s][id[sav]]+=dfs(t,lcmnum);
dp[s][id[sav]]%=mod;
}
vis[s]=false;
return dp[s][id[sav]];
}
int solve(){
num=0;
apart(k);
if(lcm(p[1],k)!=k||lcm(p[n],k)!=k)return 0;
for(int i=2;i<n;i++){
if(lcm(p[i],k)!=k){
vis[i]=true;
}
}
return dfs(1,p[1]);
} void init(){
memset(first,-1,sizeof first);
memset(dp,0,sizeof dp);
memset(vis,0,sizeof vis);
cnt=0;
id.clear();
}
int main(){
while(scanf("%d%d%d",&n,&m,&k)==3){
init();
for(int i = 0;i < m;i++){
int f,t;
scanf("%d%d",&f,&t);
addedge(f,t,i);
}
for(int i = 1;i <= n;i++){
scanf("%d",p+i);
}
int ans=solve();
printf("%d\n",ans);
}
return 0;
}

ZOJ 3644 Kitty's Game dfs,记忆化搜索,map映射 难度:2的更多相关文章

  1. 不要62 hdu 2089 dfs记忆化搜索

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=2089 题意: 给你两个数作为一个闭区间的端点,求出该区间中不包含数字4和62的数的个数 思路: 数位dp中 ...

  2. dfs+记忆化搜索,求任意两点之间的最长路径

    C.Coolest Ski Route 题意:n个点,m条边组成的有向图,求任意两点之间的最长路径 dfs记忆化搜索 #include<iostream> #include<stri ...

  3. hdu 1078 FatMouse and Cheese (dfs+记忆化搜索)

    pid=1078">FatMouse and Cheese Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/ ...

  4. hdu 1078(dfs记忆化搜索)

    题意:容易理解... 思路:我开始是用dfs剪枝做的,968ms险过的,后来在网上学习了记忆化搜索=深搜形式+dp思想,时间复杂度大大降低,我个人理解,就是从某一个点出发,前面的点是由后面的点求出的, ...

  5. UVA 10400 Game Show Math (dfs + 记忆化搜索)

    Problem H Game Show Math Input: standard input Output: standard output Time Limit: 15 seconds A game ...

  6. 8636 跳格子(dfs+记忆化搜索)

    8636 跳格子 该题有题解 时间限制:2457MS  内存限制:1000K提交次数:139 通过次数:46 题型: 编程题   语言: G++;GCC Description 地上有一个n*m 的数 ...

  7. poj1088-滑雪 【dfs 记忆化搜索】

    http://poj.org/problem?id=1088 滑雪 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 79806 ...

  8. DFS——>记忆化搜索——>动态规划

    以洛谷P1802  5倍经验日 为例 https://www.luogu.org/problem/show?pid=1802 题目背景 现在乐斗有活动了!每打一个人可以获得5倍经验!absi2011却 ...

  9. POJ 1191 棋盘分割 【DFS记忆化搜索经典】

    题目传送门:http://poj.org/problem?id=1191 棋盘分割 Time Limit: 1000MS   Memory Limit: 10000K Total Submission ...

随机推荐

  1. php使用cURL实现Get和Post请求的方法

    1.cURL介绍 cURL 是一个利用URL语法规定来传输文件和数据的工具,支持很多协议,如HTTP.FTP.TELNET等.最爽的是,PHP也支持 cURL 库.本文将介绍 cURL 的一些高级特性 ...

  2. mysql 权限控制

    1.mysql的权限是,从某处来的用户对某对象的权限. 2.mysql的权限采用白名单策略,指定用户能做什么,没有指定的都不能做. 3.权限校验分成两个步骤: a.能不能连接,检查从哪里来,用户名和密 ...

  3. hdu 1115 Lifting the Stone

    题目链接:hdu 1115 计算几何求多边形的重心,弄清算法后就是裸题了,这儿有篇博客写得很不错的: 计算几何-多边形的重心 代码如下: #include<cstdio> #include ...

  4. C++模板(基础)

    本文转至:http://www.cnblogs.com/gw811/archive/2012/10/25/2738929.html C++模板 模板是C++支持参数化多态的工具,使用模板可以使用户为类 ...

  5. 有关使用Maven常见问题总结(Eclipse中使用Maven、Maven项目部署到tomcat等问题)

    http://blog.csdn.net/sunitjy/article/details/42709311 ********************************************** ...

  6. 转载 - LINUX下查看CPU使用率的命令

    几个常用的命令,一些不错的解释 http://blog.csdn.net/wengpingbo/article/details/6302058 1.top 使用权限:所有使用者 使用方式:top [- ...

  7. python字符串替换的2种有效方法

    python 字符串替换可以用2种方法实现:1是用字符串本身的方法.2用正则来替换字符串 下面用个例子来实验下:a = 'hello word'我把a字符串里的word替换为python1用字符串本身 ...

  8. java 生成随机数

    本段代码是生成的六位随机数.也可修改生成任意位随机数. int[] array = {0,1,2,3,4,5,6,7,8,9}; Random rand = new Random(); for (in ...

  9. TCP 连接建立和断开,以及状态转换

    1. TCP报文结构 TCP是一种可靠.面向连接.全双工的传输层协议,其报文格式如下所示:      源端口.目的端口:16位长.标识出远端和本地的端口号.     顺序号:32位长.表明了发送的数据 ...

  10. python语法笔记(七)

    python标准库 Python有一套很有用的标准库(standard library).标准库会随着Python解释器,一起安装在你的电脑中的.它是Python的一个组成部分.这些标准库是Pytho ...