摘要:题目见此:http://cxsjsx.openjudge.cn/2013weekend/5G/解题思路:广搜守卫要走两步,需要特殊处理。我的处理方法是遇到守卫把,就在把这个点重新加入队列,下一次再取出,这样就保证了队列的优先性。也可以直接用优先队列。贴代码: 1 #include 2 #include 3 #include 4 using namespace std; 5 struct Point 6 { 7 int x, y, time; 8 bool stay; 9 Point():stay(0){}10 };11 Point p, ne;12 int r, ...
阅读全文
摘要:题目见此:http://cxsjsx.openjudge.cn/2013weekend5a/H/解题思路:典型的01背包,不过是二维限制的最后要把V2扫一遍找伤血最少的情况贴代码: 1 #include <iostream> 2 #include <algorithm> 3 using namespace std; 4 5 int N, V, V2, dp[1000][500]={0}, c1[100], c2[100]; 6 7 int main() 8 { 9 cin >> V >> V2 >> N;10 for(int i=1
阅读全文
摘要:题目见此:http://cxsjsx.openjudge.cn/2013weekend5a/F/解题思路:简单题,求两次最大下降子序列贴代码: 1 #include <iostream> 2 #include <algorithm> 3 using namespace std; 4 5 int h[110], a[110]; 6 7 int main() 8 { 9 int k, n;10 cin >> k;11 while(k--)12 {13 cin >> n;14 for(int i=1 ; i<=n ; i++)15 ...
阅读全文
摘要:题目见此:http://cxsjsx.openjudge.cn/2013weekend5a/E/解题思路:第一反应当然是模拟,但后来一想其实不用,每个节点只有两种情况:拓展出2个或3个节点,只需要记录下这两种节点的数目即可用a表示拓展3个节点的数目,用b表示总数,所以b-a即为拓展2个节点的数目,用s表示拓展出来的节点的数目,即:s=(b-a)*2+a*3=2*b+a,下一次b=s即可贴代码: 1 #include <iostream> 2 using namespace std; 3 4 int main() 5 { 6 int n; 7 cin >> n; 8 i.
阅读全文
摘要:题目见此:http://cxsjsx.openjudge.cn/2013weekend/5D/解题思路:一看就是背包问题,但要求算必须使用的,第一反应时枚举去掉每一种物品,看看能不能拼出V,结果超时(必然的)正确思路是,当判断第i个物品是否必要时,只需判断前i-1种物品和后i+1至N种物品凑起来能否拼出V即可因此在这个思路下,我们首先要保存二维数组,便于提取中间结果,而且要注意使前i-1物品花费的空间+后面物品花费的空间和要为V贴代码: 1 #include 2 #include 3 #include 4 using namespace std; 5 6 const int MAXN ...
阅读全文
摘要:题目见此:http://cxsjsx.openjudge.cn/2013weekend5a/B/解题思路:确实是简单任务贴代码: 1 #include <stdio.h> 2 3 int main() 4 { 5 int t, n, a[110]; 6 scanf("%d", &t); 7 while(t--) 8 { 9 scanf("%d", &n);10 for(int i=n ; i>=0 ; i--)11 scanf("%d", &a[i]);12 if(n == 0)13 ...
阅读全文
摘要:题目见此:http://cxsjsx.openjudge.cn/2013weekend5a/A/解题思路用一个二维win数组表示双方出拳后的结果,1为A赢,-1为B赢,最后加到结果上贴代码: 1 #include <iostream> 2 using namespace std; 3 4 int win[3][3] = {0, 1, -1, -1, 0, 1, 1, -1, 0}; 5 int pa[101], pb[101]; 6 int main() 7 { 8 int k, n, na, nb; 9 cin >> k;10 while(k--)11 {1...
阅读全文
摘要:题目见此:http://poj.grids.cn/practice/2251/解题思路:一道BFS简单题,可以用来练手唯一值得说一下的就是31,32行处不要写成x=i, y=j, z=k,因为i、z表示层数,j、x表示行数,k、y表示列数贴代码: 1 #include <iostream> 2 #include <queue> 3 #include <string.h> 4 using namespace std; 5 6 bool b[32][32][32]; 7 int r, c, l; 8 int dx[6]={0, 0, 1, 0, 0, -1},
阅读全文
摘要:题目见此:http://poj.grids.cn/practice/4001/(这里POJ指百练的OJ)解题思路:BFS练手题,RE了好几次……原因是28行处一直写成n>0,应该为n>=0首先要想到用一个数组来储存是否访问过,这点比较重要在判断是否插入队列时要做一些判断,这里我自己的判断感觉不是很严谨,不过总算过了,没有加剪枝贴代码: 1 #include <iostream> 2 #include <queue> 3 using namespace std; 4 bool b[400002] = {0}; 5 6 int main() 7 { 8 queu
阅读全文
摘要:题目见此:http://poj.grids.cn/practice/2559/多种解法,经典好题啊!解法一:解题思路:这题的基本思想是找出每一个矩形的左右边界(即左右边第一个比他高的),但如果直接对每一个矩形暴搜会超时。于是可以dp一下:如果它原有左边界的左边第一个,比他本身还要高,那么它原有左边界的左边第一个的左边界就是它的左边界。晕了吧~看代码:tmp = i; //先把左边界设为自己while(arr[i] <= arr[tmp-1] && tmp > 1) tmp = left[tmp-1]; 右边界同理还要注意一点,就是tmp > 1 这句一定不能缺
阅读全文
摘要:题目见此:http://acm.hdu.edu.cn/showproblem.php?pid=2544用来熟悉Dijkstra算法的好题解题思路:Dijkstra+优先队列优化如果把第14行去掉时间用时会多15ms贴代码: 1 #include <stdio.h> 2 #include <string.h> 3 #include <queue> 4 using namespace std; 5 6 const int MAXN = 101; 7 const int INF = 0xfffffff; 8 struct Node 9 {10 int to, va
阅读全文
摘要:题目见此:http://acm.hdu.edu.cn/showproblem.php?pid=1874解题思路:典型的最短路径,用Dijkstra+优先队列优化注意一点:道路是双向的,且两个城市之间可能有多条双向路,但这里我没有预处理,用vector来find一下其实也挺麻烦的,如果重复多的话应该预处理贴代码: 1 #include <stdio.h> 2 #include <string.h> 3 #include <queue> 4 #include <iostream> 5 using namespace std; 6 7 const in
阅读全文
摘要:题目见此:http://poj.grids.cn/practice/1821这道题想了一晚上啊,结果连最朴素的dp方程都列不出来……差距额于是第二天看了很多人的解题报告,看完还是半懂不懂,不过最后看这个看懂了:http://www.abandonzhang.com/archives/554(下面是脑残型详解)解题思路:这题看上去比较像背包,不过如果直接套背包模板肯定是不行的。这题比较容易想到的是有两个状态,dp[i][j]表示考虑了i个工人在第j个位置。比较难的是处理j与s[i]的位置关系。首先要明确一点,j表示第j个位置,就是说我们只考虑包括j之前的位置,也就是说,我们要把j看成是我们的视野
阅读全文
摘要:囧……在EOJ里怎么找不到提交的地方?求问,哪里有提交这道题的地方?不过把代码写出来了 1 #include <iostream> 2 #include <algorithm> 3 using namespace std; 4 5 struct MQ 6 { 7 int pos[101]; 8 long long val[101]; 9 int head, tail, winlen;10 void reset(const int& _winlen)11 {12 head = 0, tail = -1, winlen = _winlen;...
阅读全文
摘要:题目见此:http://poj.grids.cn/practice/1742传说中的男人八题解题思路:第一反应当然是多重背包了,不过写了一个没有优化的直接超时,果然是男人八题之一额~于是用单调队列优化,AC后来上网一查,原来还可以有简单方法。这道题跟其他背包还比较不一样,是要找有几个合适的,而不是求最优解。用f数组表示总共j的钱可不可以被组合出(bool),初始化为f[0]=1,f[其余]=0;再用use_count[j]数组表示当我们用到c[i]面值的银币时,组合出j的钱需要用到的c[i]的次数(拗口~),对每一个c[i]都把它初始为0。当我们想用到c[i]面值的银币时,我们把所有可能用到c
阅读全文
摘要:题目见此:http://poj.grids.cn/practice/1276解题思路:一看就是多重背包,没什么说的了……一开始不会单调队列优化,后来写了个优化了,可以对照着看看,加深理解未用单调队列优化: 1 #include <iostream> 2 #include <string.h> 3 using namespace std; 4 #define sum(a, b) a+b 5 const int MAXN = 11, MAXV = 100010; 6 int f[MAXV], c[MAXN], w[MAXN], n[MAXN], N, V; 7 8 void
阅读全文
摘要:题目见此:http://poj.grids.cn/practice/1014解题思路:如果做过几道多重背包的题的话,很明显可以看出是用多重背包,V = 总数/2, N = 6, n数组就是不同大小大理石的个数。我们可以采用“输出方案数”的做法:在背包中用sum,初始化f[0] = 1, f[其余] = 0, 最后只要考察f[V]的值是不是0(方案数是不是0)即可。贴代码: 1 #include <iostream> 2 #include <string.h> 3 using namespace std; 4 #define sum(a, b) a+b 5 const i
阅读全文
摘要:题目见此:http://acm.hdu.edu.cn/showproblem.php?pid=3415解题思路:这题一看就和POJ2823很相似,都是要求一段区间内的最大值,不同点有二:这里是循环的,这里是求和最大。方程很明显:dp[i]=sum(i)-min(sum(j))其中{i-K<=j<i},要注意这里是min观察j的范围,符合单调队列的要求,而j小于i,所以把i从小到大循环怎么处理循环呢?处理循环比较简单的方法是扩成二倍数组,这里可以采用这个做法。很明显求和必须要预处理,sum[i]表示到二倍扩充后的数组的i位置前的和,注意这样做的合理性在于我们只关注sum的差,即相对值
阅读全文
摘要:题目:http://acm.hdu.edu.cn/showproblem.php?pid=3401这个题在http://www.cnblogs.com/ka200812/archive/2012/07/11/2585950.html中先看了一遍,但是自己写的时候一直WA,原来是预处理没有做好……题目还是要自己做一遍才能理解啊,光看别人代码是看不懂的思考过程:首先看出这是个dp题,然后想状态:肯定有一个表示天数的状态,用i表示;接着我的第一反应是有一个表示买入或卖出的状态,但这个状态的上下限是不定的(跟i有关),接着注意到每天拥有的最多股数是MaxP,所以用就j表示这天拥有的股数。列dp方程:三
阅读全文