
洛谷
「已注销」
这个作者很懒,什么都没留下…
展开
-
洛谷—P1064 金明的预算方案 题解
题目链接: P1064 金明的预算方案解题思路: 带有附件的背包问题,它属于01背包的变式。每一个物品最多只有两个附件,那么我们在对主件进行背包的时候,决策就不再是两个了,而是五个。01背包的决策1.不选,然后去考虑下一个2.选,背包容量减掉那个重量,总值加上那个价值。这个题的决策是五个,分别是:1.不选,然后去考虑下一个2.选且只选这个主件3.选这个主件,并且选附件14.选这个主件,并且选附件25.选这个主件,并且选附件1和附件2.代码:#include<iostream&g原创 2020-11-06 21:29:05 · 238 阅读 · 0 评论 -
洛谷—P1833 樱花题解
题目链接: P1833 樱花解题思路: 将第i种物品分成若干件物品,其中每件物品有一个系数,这件物品的费用和价值均是原来的费用和价值乘以这个系数。例如,如果p[i]为13,就将这种物品分成系数分别为1 , 2 , 4 , 6 的四件物品,则这四件物品的费用为kw[i]、价值为kv[i]。(k是物品的数目,而w[i]和v[i]分别为费用和价值)。这样我们就把一件物品拆分为多个物品,然后我们可以使用01背包求解,因为现在每个物品只有1件。代码:#include<iostream>#inclu原创 2020-11-06 20:55:16 · 657 阅读 · 1 评论 -
洛谷—P1541 乌龟棋题解
题目链接: P1541 乌龟棋解题思路: 因为当前的状态与我们用过的牌有关,所以用一个四维数组记录当前已经用掉的牌数dp[a][b][c][d],这个状态可以由上一个状态dp[a - 1][b][c][d]、dp[a][b - 1][c][d]、dp[a][b][c - 1][d]、dp[a][b][c][d - 1]转移而来。所以我们可以枚举每种牌的数量,计算使用当前状态的牌到达的位置即可。 for (int a = 0; a <= f[1]; a++) { for (int b = 0;原创 2020-10-27 21:47:15 · 307 阅读 · 0 评论 -
洛谷—P3842 [TJOI2007]线段题解
题目链接: P1541 乌龟棋解题思路: 从第i-1行走到第i行只有两种可能->要么从第i-1行线段的最左端,要么从第i-1行的最右端。所以我们可以定义二维数组来表示这个状态。用f[i][0]表示走完第i行且停在第i行的左端点最少用的步数。f[i][1]同理,停在右端点的最少步数。dp[i][0] = min((dp[i - 1][0] + dis(r[i], l[i - 1]) + r[i] - l[i]), dp[i - 1][1] + dis(r[i], r[i-1])+ r[i] - l[原创 2020-10-27 21:14:53 · 332 阅读 · 0 评论 -
洛谷—P1095 守望者的逃离题解
题目链接:P1095 守望者的逃离解题思路:首先DP的套路就是先找状态,这题也找不出其他的状态了,只有时间一个,所以用f[i]表示时刻i能走多远。仔细一想实际上决策只有跑、闪现、停三种决策然而闪现的耗蓝要和跑步一同计算十分麻烦。于是把它们分开算:先算闪现的,有以下框架for i in range(1,t)如果蓝量够闪现,耗蓝如果不够停下,回蓝接下来算走路,其实走路的只要维护之前算出的即可因为之前已经算了只用闪现走多远,那么只要判断如果这一秒不闪或者不停(因为跑步不耗蓝)是否比之前更优即可原创 2020-10-25 21:18:48 · 471 阅读 · 0 评论 -
2020-10-20
题目链接:P1057 传球游戏解题思路:这题要用到环型DP的思路。不妨设小蛮在1号,所有人的编号是 1~n。状态dp[i][j]表示所有已经传了i次球,且最后球在编号是j的小朋友手上的方案。我们可以发现,任何一个位置都只能从左边和右边传过来,那么他只能从他左边和他右边的同学手上接到球,那球传到他手上的路径数是不是球传到他左边同学的路径数与球传到他右边同学的路径数之和?dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j + 1];注意:要在n和1的时候特判。代码:#原创 2020-10-20 21:55:23 · 141 阅读 · 0 评论 -
洛谷—P1406 方格填数题解
题目链接: P1406 方格填数解题思路: 注意条件每行每列每个对角线上整数的和都相等,我们可以在读入数据的时候求出这个和。然后把数据排序求出字典序最小的方案。那么我们应该怎么搜索呢?很显然我们不能用x+dx[i]这样来搜索下一个点,因为我们要满足和相等的条件。if (y == n + 1) {//一行填完后,转下一行,并把和置为0 y = 1; x += 1; sumk = 0; }到达终点条件时:if (x == n + 1) { for (int i = 1; i <原创 2020-10-19 21:08:07 · 348 阅读 · 0 评论 -
洛谷—P3613 【深基15.例2】寄包柜题解
题目链接:P3613 【深基15.例2】寄包柜vector解题思路: 首先我们期望的一个强大的数组应该存放这个三个元素:第 i 个柜子的第 j 个格子以及存入的物品 k 。那么怎么去实现呢?第一个想到的肯定是二维数组,但是这道题目的范围太大会MLE,所以我们可以用变长数组vector。设一个结构体const int MAX = 100005;struct Node{ //s用来记录desk[i]的元素个数,表示第i个柜子已存s次物品 //num表示第i个柜子的第num个格子存入一个物品原创 2020-10-18 16:02:06 · 760 阅读 · 0 评论 -
洛谷—P1434 [SHOI2002]滑雪题解
题目链接: P1434 [SHOI2002]滑雪解题思路: 在这道题中dfs每种情况是,可能这个点之前已经搜过了,没必要再去搜索了,因此不如存储记住,就没必要再去dfs了。所以我们要记忆化搜索解决这道题。这题每个点出发都有可能,所以我们每个点都要开始dfs,最后取他们的最大值。用dp[maxn][maxn]去保存当前点长度的最大值。dfs部分和类似的迷宫差不多,用两个数组表示4个方向:const int dx[] = { 1,0,-1,0 };const int dy[] = { 0,1,0,-1原创 2020-10-17 21:22:40 · 442 阅读 · 0 评论 -
洛谷—P1535 [USACO08MAR]Cow Travelling S 题解
题目链接: P1535 [USACO08MAR]Cow Travelling SBFS解题思路: 因为要统计次数,不能简单地跳过一个被经过的点,(注意这点我们不是要求达到某个点的最短时间,而是求次数,所以我们不可以跳过这个点,比如说如果案例的时间改为10,那么我们求出的次数一定要小于真正的答案)。可是这样的话,状态量会爆炸。所以我们可以采用记忆化设dp[i][j][k]表示在第k分钟到达点(i,j)的方案数,以地点+时间作为状态。避免同一状态被反复拓展。这样,状态量将减少至最多100* 100* 15。原创 2020-10-17 17:40:39 · 335 阅读 · 0 评论 -
洛谷—P1032 字串变换题解
题目链接: P1032 字串变换解题思路: 题意已经把做法写得特别露骨了。。。最小步数,最多6个变换规则。。。。广搜自不必说,不仅可以寻找解而且还能判断步数(根据广搜首解最优的性质可以得到)。开两个数组记录串的转换关系,然后以a串(原串)为起点开始搜索,搜索目标是b串。需要一个map记录某个串是不是被搜到过,如果已经搜过了就不再继续搜 。我们枚举所有可能的转换手段,枚举当前队列中队头那个串的每一个位置,然后去尝试拼接,如果有相同串则拼接。拼接函数如下:inline string getStr(strin原创 2020-10-15 20:39:07 · 407 阅读 · 0 评论 -
洛谷—P1443 马的遍历题解
题目链接:P1443 马的遍历解题思路: 直接BFS,用数组step记录步数即可。代码:#include<iostream>#include<queue>#include<iomanip>#include<cstdio>#include<cstring>using namespace std;const int dx[] = { 2,-2,2,-2,-1,1,-1,1 };const int dy[] = { 1,1,-1,-1原创 2020-10-14 21:28:58 · 359 阅读 · 0 评论 -
洛谷—P1162 填涂颜色题解
题目链接:P1162 填涂颜色解题思路: 用DFS搜索,用vis数组记录当前点有没有访问过。如果没有就输出2,否则输出0。实际上这是不对的。看下面:我们的判断数组是这个样子,从DFS(1,1)开始搜索bool check(int x, int y) { if (x<1 || x>n || y<1 || y>n) { return 0; } return 1;}然后提交会发现过不了。这是因为dfs在先搜索的时候应该搜索到矩阵的外面一圈(0, n + 1) 否则的话原创 2020-10-14 21:26:30 · 571 阅读 · 0 评论 -
洛谷—P5194 [USACO05DEC]Scales S题解
题目链接: P5194 [USACO05DEC]Scales S解题思路: 虽然题目中说n≤1000 ,但考虑到“每个砝码的质量至少等于前面两个砝码的质量的和”这一条件,可以推出 n≤30 。所以可以用搜索。可以考虑折半搜索。把40个砝码分成两半,搜索出两边分别能测量的重量,然后枚举其中一边的所有可以测量到的重量,将另外一边排序后二分,使得相加不超过C且尽量大。在所有答案中取min即可。代码:#include<iostream>#include<algorithm>usin原创 2020-10-13 20:19:28 · 675 阅读 · 0 评论 -
洛谷—P1019 单词接龙题解
题目链接: P1019 单词接龙解题思路: 用DFS进行搜索,用vis[i]表示这个单词用过的次数,然后进行查找。首先从给定的头开始进行dfs然后进行遍历每个单词1.看这个单词是否用过的次数<2。2.看这个单词是否可以连接上。然后需要暴力一遍拼的字符串长度来判断是否可以连接,可以的话就进行连接,然后继续深搜下去。否则话就回溯回来。代码:#include<iostream>#include<algorithm>#include<cstring>usi原创 2020-10-13 19:26:48 · 271 阅读 · 0 评论 -
洛谷—P1378 油滴扩展题解
题目链接:P1378 油滴扩展解题思路: 这道题的关键在于怎么求出当前点可以拓展的最大半径。想一想,这个半径要满足什么条件?这个半径是不是当前点接触到其他油滴或者框子的边界的最大距离。inline double getDistance(int i) { double s1 = min(abs(x[i] - xa), abs(x[i] - xb)); double s2 = min(abs(y[i] - ya), abs(y[i] - yb)); double ans = min(s1, s2);原创 2020-10-12 23:17:06 · 269 阅读 · 0 评论 -
洛谷—P4799 [CEOI2015 Day2]世界冰球锦标赛题解
题目链接:P4799 [CEOI2015 Day2]世界冰球锦标赛题目大意: 给定钱数,问要多少种观赛方案,可以一场都不看。题解思路: 这道题要用到一种搜索方法——折半搜索。具体方法为:我们先把数据分为前后两部分,分别进行搜索,用两个数组分别存储每次的答案。折半搜索的统计/组合答案是最复杂的部分,这个题我们应该如何统计呢?先将第一个数组排序,然后枚举第二个数组的每一个数设为w,算出总钱数-w也就是剩余的钱数,然后找出第一个数组中第一个大于剩余的钱数的位置,因为第一个数组已经排好序,所以在这个位置之前的数原创 2020-10-10 23:13:08 · 370 阅读 · 0 评论 -
洛谷—P1074 靶形数独题解
题目链接: P1074 靶形数独题目大意: 在99的方格填数,要求每个数字在每个小九宫格内不能重复出现,每个数字在每行、每列也不能重复出现。求最大分数。题解思路: 这道题和八皇后的思路差不多。只是要判断的状态多一些。我们首先先一个问题,我们拿到这个99宫格就开始搜索吗?有没有可能处理一下这个9*9宫格可以剪枝?想一下我们要填的是空白方格,如果行要填的空白方格越少,那么搜索的层数就越少,搜索花的时间就越少。我们可以建一个结构体struct Row{ int zeroNum, lineIndex原创 2020-10-10 20:31:18 · 378 阅读 · 0 评论 -
洛谷—P1331 海战题解
题目链接: P1331 海战题目大意: 在R*C的矩形块中放置船。如果船的位置合法计算出船的数目,否则输出“Bad placement.”题解思路: 这道题的难点在于判断是否有船相邻。通过自己模拟的数据可以得出结论:方法一: 如果图是不和法的,一定存在如下结构:# # . #或# ## .或# .# #或. ## #即在一个2*2的方格中有三个#就表示船的位置放置有错误。inline bool isValid(int x, int y) { int sum =原创 2020-10-07 16:05:24 · 1208 阅读 · 0 评论 -
洛谷—P3956 棋盘题解
题目:P3956 棋盘题目思路: 求花费最小金币数,需要用BFS(当然DFS也可以)。我们将到达下一个格子的各个状态全部压入队列中。但注意这句话:但这个魔法不能连续使用, 而且这个魔法的持续时间很短,也就是说,如果你使用了这个魔法,走到了这个暂时有颜色的格子上,你就不能继续使用魔法。这意味着我们需要在创建结构体时要多加上一个属性判断它是否在上一个格子用过了魔法。代码:#include<iostream>#include<algorithm>#include<q原创 2020-09-20 23:54:03 · 564 阅读 · 0 评论 -
洛谷—P1219 [USACO1.5]八皇后 Checker Challenge题解
题目:P1219 [USACO1.5]八皇后 Checker Challenge题目大意: 在n*n的棋盘上放棋子,要求所有的棋子不在同一行,同一列和同一对角线上,问有多少种放法,并输出前三种情况。解题思路: 假如我们放第i个棋子,这个棋子假设放在第i行,那么这个棋子要满足什么条件才可以放下去?是不是要满足棋子不在同一行,同一列和同一对角线上这一条件?那么我们如何得知是不是满足条件呢?很简单,用数组表示状态。我们用三个数组分别表示列(a)的状态,左下到右上的对角线(b)的状态,左上到右下的对角线(c)的原创 2020-09-13 23:25:38 · 579 阅读 · 0 评论 -
洛谷—P1036 选数题解
题目:P1036 选数题目大意: 从n个数中选出k个数,把这k个数相加得到的和是素数的情况有多少种解题思路: 这道题的难点是如何去重。有两种方法,一是通过vis数组记录那个数已经被访问过。二是不降原则,将数字从小到大排序,保证枚举的这些数是升序排列。代码:题解一:#include<iostream>#include<algorithm>using namespace std;const int maxn = 1000;int n, k,a[maxn],ans,vis原创 2020-09-13 16:52:12 · 401 阅读 · 0 评论 -
洛谷—P1126 机器人搬重物题解
题目:P1126 机器人搬重物题目大意: 给出由0,1组成的地图,机器人在地图的中心格点上移动,机器人可以向前移动1步;向前移动2步;向前移动3 步;向左转;向右转。每个指令所需要的时间为1 秒。问到达目的地的最短时间。解题思路: 这道题目一看就要用广度优先搜索来求解,不过要注意一个地方,那就是机器人是有体积的,所以边界和障碍物的四周,不能走,所以边界条件判断时,n和m各要减1,地图还要进行转换(getMap函数)。重点来了,机器人从起点开始可以走1步,走两步,走三步以及转弯。也就是说把左转右转,走一步原创 2020-09-13 16:31:47 · 366 阅读 · 0 评论 -
洛谷 P5198 [USACO19JAN]Icy Perimeter S题解
题目:P5198 [USACO19JAN]Icy Perimeter S题目大意:给出一个由.和#组成的二维矩阵,每一个连通块都有一个面积和周长,求面积最大的连通块的面积和周长,若有多个面积一样大的,输出周长最小的那个。解题思路:根据题意,二维矩阵中最大的#连通块即为我们所求的面积,这个很好求,只要深搜或广搜。难点是理解周长的含义(不知道你有没有理解为什么案例的周长为22)。看下图(懒得画图了,来源题目的讨论区),这是我数的周长8+9=17。注意超出边界的地方也是我们要算的周长。但实际上周长是这原创 2020-09-11 15:41:40 · 638 阅读 · 0 评论