题目代号:HDU2923 题目链接:http://poj.org/problem?id=2923 Relocation Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 3472 Accepted: 1422 Description Emma and Eric are moving to their new house they bought after returning from their honeymoon. Fortu…
好牛b的思路 题意:一系列物品,用二辆车运送,求运送完所需的最小次数,两辆车必须一起走 解法为状态压缩DP+背包,本题的解题思路是先枚举选择若干个时的状态,总状态量为1<<n,判断这些状态集合里的那些物品能否一次就运走,如果能运走,那就把这个状态看成一个物品.预处理完能从枚举中找到tot个物品,再用这tol个物品中没有交集(也就是两个状态不能同时含有一个物品)的物品进行01背包,每个物品的体积是state[i],价值是1,求包含n个物品的最少价值也就是dp[(1<<n)-1](dp…
我自己只能想出O( n*3^m )的做法....肯定会T O( nm*2^m )做法: dp( x, s ) 表示考虑了前 x 个商店, 已买的东西的集合为s. 考虑转移 : 先假设我们到第x个商店去, so初始时 dp( x, s) = dp( x-1, s ) + d[x] 然后我们可以对第x个商店做01背包, dp(x, s + {h} ) = min( dp( x, s + {h} ) , dp( x, s) + c[x][h]) ) ( h ∉ s ). 之后我们再比较到第x个商店划不…
题意:给你汽车容积c1,c2,再给你n个包裹的体积,问你最少运几次能全运走 思路:用2进制表示每次运送时某物在不在此次运送之中,1在0不在.我们把运送次数抽象成物品价值,把状态抽象成体积,用一个dp[ i ] 记录完成状态i的最少步数那么就转化为了01背包问题,得到状态转移方程dp[ j|state ] = min( dp[ j|state ],dp[j] + 1 ),state为运送时物品的状态. 然后讲一下可能会有点看不懂的judge()的一段代码 for(int j = c1;j >= v…
树形DP和状压DP和背包DP 树形\(DP\)和状压\(DP\)虽然在\(NOIp\)中考的不多,但是仍然是一个比较常用的算法,因此学好这两个\(DP\)也是很重要的.而背包\(DP\)虽然以前考的次数挺多的,但是现在基本上已经成了人人都能AK的题了,所以也不经常考了. 树形DP 树形DP这个非常特殊,他好像和是唯一一个用深搜实现的DP,所以我们学好它也是应该的,其特点是通过深搜. 思路 先找到一个根节点,然后预处理出所有子树的大小. 然后深搜把最底层的子节点得状态处理出来. 递归回溯到根节点,…
题目大意:两个人从2~n中随意取几个数(不取也算作一种方案),被一个人取过的数不能被另一个人再取.两个人合法的取法是,其中一个人取的任何数必须与另一个人取的每一个数都互质,求所有合法的方案数 (数据范围毕竟很小,乍一看也不是啥打表找规律的题) 和我之前做过的一道题很类似hdu 6125,但这道题由于题面看起来很玄学,所以正解更难想 但还是 状压DP+分组背包 的套路 因为500以内的任何一个数,只会有一个大于19的质因子,所以对2 3 5 7 11 13 17 19这8个质数进行状压,然后每个数…
题目大意: 给出n和k,求从小于等于n的数中取出不超过k个,其乘积是无平方因子数的方案数.无平方因子数:不能被质数的平方整除. 题目分析: 10(枚举\(n\le8\)),40(简单状压\(n\le16\)),70(高级状压\(n\le30\)),100(正解状压n\le500,k\le500). 对于前百分之70,由于\(n\le30\),质数只有10个,直接状压水. 正解(状压dp+分组背包): 注意到1~n中每个数含有的大于\(\sqrt{n}\)的质因数最多有1种,而\(\sqrt{n}…
problem:给定N,K.表示你有数1到N,让你最多选择K个数,问有多少种方案,使得选择的数的乘积无平方因子数.N,K<500: solution:显然可以状压DP做,但是500以内的素数还是蛮多的,无法高效得DP.   但是我们注意到,大于sqer(N)的素数,同一类最多用一个,这不就是分组背包吗. 所以我们只有小于sqrt(N)的素数用常规的DP,否则用分组背包. dp[i][j]表示选择了i个数,其中小于sqrt(N)的素数状态为j. j<(1<<8): 分组背包:我们把个…
没什么可说的,入门级状压DP.直接撸掉 #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <algorithm> #include <cmath> #include <vector> #include <map> #include <queue> #include <stac…
思路: 用状压DP+DFS遍历查找是否可行.假设一个数为x,那么他最远可以消去的点为x+9,因为x+1~x+4都能被他前面的点消去,所以我们将2进制的范围设为2^10,用0表示已经消去,1表示没有消去.dp[i][j]表示栈顶是i当前状态为j时能不能消去栈顶,-1代表不知道,0不行,1行.所以我们只需DFS到i==n时j是否为0,就可以知道能不能消除.更新状态时,只有栈顶到栈底元素>10才更新新的元素进栈. 代码: #include<cstdio> #include<map>…