02 2012 档案
摘要:今天也算是练习了一下记忆化搜索,这道题也包含很多值得注意的地方1、 输入的两个数不一定前者比后者大2、 变换的过程中可能会超出int范围3、 为了不超时可以作下预处理#include<iostream>#include<cstring>#include<cstdio>using namespace std;#define MAXINT 1000001int res[MAXINT];int dfs(long long t){ if(t<=1) return 1; if(t<=MAXINT && res[t]!=0) return r
阅读全文
摘要:一道很好的搜索题目,但是好久没有弄懂题意,题意大致是这样的:在一个地图上给出自己的位置‘Y’,目的位置‘T’,两种墙‘S’和‘B’,还有河‘R’,以及空地‘E’。‘S’和‘R’是不能穿过的,‘B’可以被炸毁但需要一个单位时间,每走一步也需要单位时间。求从初始位置到目的位置至少需要多长时间。dfs和bfs都可以来搜索,dfs复杂度比较高,但可以用记忆化搜索,我选择的是bfs,因为炸毁墙需要一个单位时间,所以按照平常的广搜是不行的,只能一各单位时间一个单位时间的来走,不能一次走两个单位时间。所以每次到达‘B’时,需要等待一个时间。#include<iostream>#include&l
阅读全文
摘要:题意:给出两串,两串顺序不变看能否组成第三个串。此题深搜和DP都能解决:深搜的话需要几个强有力剪枝条件1、 第三个串最后一个字符要么是串1的最后一个字符,要么是串2的最后一个字符2、 按照串1的顺序对串3进行搜索,若不匹配则该字符必是串2的下一个字符。#include<iostream>#include<cstdio>#include<cstring>using namespace std;char first[202],second[202],third[402],Left[401];int sign[402];bool flag;int check(){
阅读全文
摘要:题意也就是:一个矩形被n条线段分成n+1份,每条线段各不相交,给出几个点落在矩形内部,问各个部分有几个点。由于各个部分各不相交,线段的上、下端点也就排好序了,然后二分查找每个点落在线段左边的第一条线段,也就找出了落点的区域。#include<iostream>#include<cstdio>#include<cstring>using namespace std;int upLine[5001],lowLine[5001],res[5001],up,low,Left,Right;int IsLeft(int x,int y,int k){ return (u
阅读全文
摘要:纯属模拟,但关键分为三种情况:最大的(没有排好的)元素在最底下、在最上面、在其他位置。第一种情况:不需要排,因为已经在该在的位置。第二种情况:需要一步,从它应该在的位置翻转一下。第三种情况:需要两步,先把它翻转到最上面去,然后再从它应该在的位置翻转一次。翻转操作我用栈和队列来回倒换。#include<iostream>#include<cstdio>#include<cstring>#include<queue>#include<stack>#include<algorithm>using namespace std;#d
阅读全文
摘要:一道较难的贪心题,看了看大牛的博客才渐渐有了思路:贪心原则应该是Ci大的尽量先染色,但是由于父节点染了才能染子节点的限制使得问题不好解决了,但是Ci大的一定是在其父节点染色后立即被染色,这时大牛们的思路我也没有看明白如何证明的,但仔细一想就明白了。于是我们根据这个条件就可以将Ci大的点与其父节点合并在一起组成一个集合。这样就可以将问题规模减小。 合并后的点(即集合)的属性如何变化呢?假如设fact[i]表示集合的Ci和,iNum[i]表示i所属集合的结点个数;那么把fact[i]/iNum[i]作为贪心原则,其值大者先合并到其父节点,最终合并成一个集合。答案是怎么得出来的我看了很长时间才明白。
阅读全文
摘要:一道简单的匹配问题,行列匹配,根据题意若行大于列匹配不成功,若列大于行,大于行的部分可随意。代码如下:#include<iostream>#include<cstdio>#include<cstring>using namespace std;int map[1001][2],col[1001],match[1001],visit[1001];int dfs(int i){ int j,k; for(j=0;j<2;j++) { k=map[i][j]; if(!visit[k]) { visit[k]=1; ...
阅读全文
摘要:一道简单的树形DP,可以这么想:每个节点有可能选择也有可能不选择,而且各个子树相互独立,我用DP[i][0]表示节点i不选择所需要的最少士兵,DP[i][1]表示i节点选择所需要的最少士兵。假如j是i的儿子,因此状态转移方程可以写成如下形式:DP[i][0]+=DP[j][1] ;DP[i][1]+=min(DP[j][0],DP[j][1]);#include<iostream>#include<cstdio>#include<cstring>using namespace std;struct node{ int i,next;}S[15001];int
阅读全文