摘要:原题: 思路: 经典DP题目 但这个题有个更快的做法 开一个数组d表示序列中的数 如果目前这个数与d中最后一位符合要求 就加入 如果不符合就找到d中第一个不符合要求的并替换 相当于一直在确定这个序列是多少 详见代码 代码: #include<bits/stdc++.h> using namespac
阅读全文
摘要:原题: 思路: 考虑DP 设f[i][j]为考虑前i行,第i行选第j个的最大值 则f[i][j]=max(f[i-1][j])+d[i][j] 这道题由于有枚举成分在,如果用DFS就会超时 代码: #include <bits/stdc++.h> using namespace std; int n
阅读全文
摘要:原题: 思路: 可以采取类似于树形DP的做法 计算出从各个儿子到达目标点的方法 然后加起来,就是这个点的方法 就像是反向的计数DP 代码: #include <bits/stdc++.h> using namespace std; struct node { int u,w,nxt; }e[2000
阅读全文
摘要:原题: 思路: 考虑搜索,显然有必胜策略 对于能转移到必胜状态的,必输,因为它把必胜状态给了对方 由此可以用搜索解决 但是DFS麻烦,于是我们换一种策略 类似动规 代码: #include <bits/stdc++.h> using namespace std; int n; int f[2010]
阅读全文
摘要:原题: 思路: 经典树形DP 借此题讲解一下树形DP 顾名思义,树形DP以「子树」作为单位进行DP 由于这个性质,DFS成了实现的最好选择 先DFS求出子问题,随后得出当前规模答案。 详见代码 这个还可以用拓扑排序做 代码: #include <bits/stdc++.h> using namesp
阅读全文
摘要:原题: 1≤n≤16 思路: 一看规模,暴搜,这种题还不简单hahaha 既然要做题,我们就要想想更优解法 为什么不写一下记忆化呢? 首先我们想到的是,记忆以每一个单词开头能得到的最长长度 但是这个想法连样例都过不了 在这组样例中,以我们的想法,OIOOI显然能接的最长单词是IUUO 但以IUUO开
阅读全文
摘要:原题: 思路: 首先考虑暴搜。 对于每一个点,我记录到这一格为止,走过了多少路。然后枚举四个方向继续递归。直到彻底走不动之后,就停下来更新答案。 但是有个问题——数据规模最大100行100列,如果我以一次递归4个方向来计算,第一层4种,第二层16种,第三层64种,第四层256种,而假设我们从整个地图
阅读全文
摘要:原题: 思路: 显然是搜索 但问题在于要同时标记行、列、对角线 对角线有规律:从左上到右下,x-y是固定值,从左下到右上,x+y是固定值 由于x-y有可能是负的,所以要+n 代码: #include <iostream> using namespace std; int n,ans,book[233
阅读全文
摘要:原题: 思路: 广搜。 但队列除了记忆坐标,还要记忆步数。 在将一个点入队的时候,这个点的步数为这个点的父亲节点的步数+1,顺便把答案设了。 代码: #include<bits/stdc++.h> using namespace std; int n,m; int sx,sy; int a[405]
阅读全文
摘要:原题: 思路: 对于每一个楼层,只有上和下两种情况 将上和下分别入队跑BFS即可 代码: #include<bits/stdc++.h> using namespace std; int n,a,b; int move_count[205]; bool arrived_floor[205]; boo
阅读全文
摘要:原题: 思路: 数据范围很小(n<=20)所以考虑搜索。 最为朴素的想法——对于每一个单词,我考虑后面能接哪些单词,并分别尝试计算答案。 但是随之而来的就是一个问题——我要如何知道后面能接哪些单词? 解决方法很简单,只要匹配一下就好了。 但是,难道我每次递归,都要匹配一下吗?这肯定是不行的,时间复杂
阅读全文