摘要: 题目链接大致题意:给定一堆不定长度的小棒子,问他们能否构成一个正方形。解题思路:POJ1011的热身题,DFS+剪枝本题大致做法就是对所有小棒子长度求和sum,sum就是正方形的周长,sum/4就是边长side。问题就转变为:这堆小棒子能否刚好组合成为4根长度均为side的大棒子不难了解,小棒子的长度越长,其灵活性越差。例如长度为5的一根棒子的组合方式要比5根长度为1的棒子的组合方式少,这就是灵活性的体现。由此,我们首先要对这堆小棒子降序排序,从最长的棒子开始进行DFS剪枝,有3处可剪:1、 要组合为正方形,必须满足sum%4==0;2、 所有小棒子中最长的一根,必须满足Max_length 阅读全文
posted @ 2013-04-29 20:58 xindoo 阅读(229) 评论(0) 推荐(0) 编辑
摘要: 题目链接题意 有个小球,只能向右边或下边滚动,而且它下一步滚动的步数是它在当前点上的数字,如果是0表示进入一个死胡同。求它从左上角到右下角到路径数目。注意, 题目给了提示了,要用64位的整数。记忆化搜索方法#include #include #define ll __int64int n;ll vis[36][36];char board[36][36];ll dfs(int x,int y){ if(x==n-1&&y==n-1) return 1; if(board[x][y]=='0') return 0; if(vis[x][y]) ... 阅读全文
posted @ 2013-04-29 14:24 xindoo 阅读(160) 评论(0) 推荐(0) 编辑
摘要: 题目链接Problem DescriptionFatMouse has stored some cheese in a city. The city can be considered as a square grid of dimension n: each grid location is labelled (p,q) where 0 #include #include using namespace std;int n, k, dp[101][101];int map[101][101];int dfs(int a,int b){ if(dp[a][b]) return dp[a]... 阅读全文
posted @ 2013-04-29 10:18 xindoo 阅读(191) 评论(0) 推荐(0) 编辑
摘要: DFS(Depth First Search )一般是不用hash的,所以很多时候称之为”暴力”,也就是穷举所有情况,一般看几个我们OJ的dfs的版本的题目就可以模仿着做了,因为牵涉到递归,初学者学的时候最好能举一反三,理解其中真谛.DFS --- EASY(15)Tempter of theBoneSafecrackerPrime RingProblemRobot MotionFire Net猜数字 此题暴力仅需15msOil DepositsSum It UpRed and BlackShreddingCompanyKrypton FactorRankHow ManyEquations C 阅读全文
posted @ 2013-04-28 19:38 xindoo 阅读(130) 评论(0) 推荐(0) 编辑
摘要: 题目链接这是一道博弈的题,准确说是尼姆博弈,只要判断各项的异或值即可。代码#include const int maxn = 5000;int x[maxn];int main(){ int t, n, tmp; scanf("%d", &t); while (t--) { scanf("%d", &n); int cnt = 0; for (int i = 1; i <= n; i++) { scanf("%d",&x[i]); if (x[i] == 1) ... 阅读全文
posted @ 2013-04-27 13:49 xindoo 阅读(134) 评论(0) 推荐(0) 编辑
摘要: 题目链接 按照等级我们可以建一颗树,如图 我们可以把一个节点当做一个人,每个节点都有一个权重。按照题目意思,如果我们取了某个节点,那么他的父节点和子节点都是不能取的。按要求选取节点,使得选取节点的权重和最大。 DP,用no表示不选择i点时,i点及其子树能选出的最多人数,is表示选择i点时,i点及其子树的权值和最大。状态转移方程:—对于叶子节点 dp[k].no = 0, dp[k].no = a[k].v—对于非叶子节点i,—dp[i].no = ∑max(dp[j][0], dp[j][1]) (j是i的儿子)—dp[i].is = v + ∑dp[j].no (j是i的儿子)代码:#... 阅读全文
posted @ 2013-04-26 15:40 xindoo 阅读(172) 评论(0) 推荐(0) 编辑
摘要: 题目链接 逆序的概念大家都知道,一个数到逆序数就是该数左边大于它到数的个数。 很多没学过数据结构的人一上来肯定就是一个个数了,看看数据量500k,显然这种暴力的方法是行不通的。 我们换种想法,可以在输入过程中对每个数的逆序数求解,建一个vis数组(初始化为0),只要输入一个数,在它的位置标记为1,然后计算出它的左边一共有多少数被标记了就可以知道多少个数比他小了,当然逆序数也就知道了,求从左到右数的和,这是树状数组最擅长的了。 但我们看看每个数的范围是0 ≤ a[i] ≤ 999,999,999,我们不可能开那么大的数组,即使开的了也会浪费很多,这个时候我们就要对数据进行离散化处... 阅读全文
posted @ 2013-04-25 16:09 xindoo 阅读(159) 评论(0) 推荐(0) 编辑
摘要: 并查集小结并查集大体分为三个:普通的并查集,带种类的并查集,扩展的并查集(主要是必须指定合并时的父子关系,或者统计一些数据,比如此集合内的元素数目。)POJ-1182经典的种类并查集POJ-1308用并查集来判断一棵树。。注意空树也是树,死人也是人。POJ-1611裸地水并查集POJ-1703种类并查集POJ-1988看上去似乎和种类并查集无关,但其实仔细想想,就是种类并查集。。。只不过是种类数目无穷大,通过合并,可以确定两个物品之间的种类差(即高度差)POJ-2236裸地并查集,小加一点计算几何POJ-2492裸地种类并查集POJ-2524又是裸地并查集POJ-1456常规思想是贪心+堆优化 阅读全文
posted @ 2013-04-24 11:36 xindoo 阅读(111) 评论(0) 推荐(0) 编辑
摘要: 题目链接 这并不是一题裸的01背包,它在简单到01背包上还加了一个限制条件Q,如果没有Q,这完全是一题裸01背包。 对于这个题目,我们只要加上排序对某些物品进行优先处理就好了。 想想我们为什么要排序, 举个简单的例子,如果数据中出现这样到情况 5 9 3、 6 6 5、5 6 3…… 对5 9 3 处理的时候他只能求出dp[9]然后6 6 5只能在dp[9]的基础上继续处理,它要用到dp[6]、dp[7]……,而这些全是零,但这些一直会是0吗?不是在处理5 6 3的时候可以得到这些值,但6 6 5已经被处理了,它再也不会用的这些了,所以怎么得到正确的结果? 如果我们对5 6 3优先处理就... 阅读全文
posted @ 2013-04-24 09:00 xindoo 阅读(135) 评论(0) 推荐(0) 编辑
摘要: 题目链接 虽然每件物品的数目并不是1,可能有多个,但我们完全可以把这个题目转化成01背包来解决。 可以把多件相同的物品合并成一件,马上就变01背包了。#include #include #include using namespace std;int dp[105];int pr[105];int cnt[105];int w[105];int main(){ int n, m, t; scanf("%d", &t); while (t--) { scanf("%d%d", &n, &m); for (int i = 1; i = 阅读全文
posted @ 2013-04-23 20:01 xindoo 阅读(126) 评论(0) 推荐(0) 编辑