[hdu4628 Pieces]二进制子状态,DP】的更多相关文章

题意:给一个长度为16的字符串,每次从里面删掉一个回文序列,求最少需要几次才能删掉所有字符 思路:二进制表示每个字符的状态,那么从1个状态到另一个状态有两种转移方式,一是枚举所有合法的回文子序列,判断是否是当前状态的子状态,再转移,二是枚举当前状态的所有子状态来转移.前者最坏复杂度O(2^16*2^16) = O(几十亿),而后者最坏只有(i:1->16)Σ2iC(16,i) = O(几千万). 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20…
题目:http://poj.org/problem?id=3254 利用二进制压缩状态,每一个整数代表一行的01情况: 注意预处理出二进制表示下没有两个1相邻的数的方法,我的方法(不知为何)错了,看到了别人的优美方法: 再进行DP即可. 代码如下: #include<iostream> #include<cstdio> using namespace std; int m,n,a[15],num[15],p[3005],f[15][3005],tot,INF=100000000,a…
题意:给你一个长度小于等于16的字符串,每次可以删除一个回文传,问你最少删除干净的字数. 状态+dp dp[i] = min(dp[i],dp[j]+dp[j^i]);(j是i的字串): 连接:http://acm.hdu.edu.cn/showproblem.php?pid=4628 代码: #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #in…
题目链接 错解: #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> using namespace std; typedef long long LL; ; int a[N]; int m[N][N]; // dp[i][j] 状态结尾的值 LL dp[N][N];// 前i个元素有序最大值小于等于a[j]的最值 int n; int main () {…
给定n个点(n是偶数)使得两个点两两配对,最后总的距离和最小. 用是表示集合,那么dp[s]表示集合s配对后的最小距离和  , 状态转换方程为  表示集合中任意拿两个元素配对,然后转移为更小的两个集合的点集配对.i=min(s)表示i为集合中的第一个元素,因为第一个元素肯定要配对的, 所以找到集合中的第一个元素后,我们枚举要配对的另外一个元素j,j>i && j属于s 我们用二进制表示一个集合,1表示该元素存在,0表示不存在,然后进行状态转移 我们不需要担心一个状态的子状态没有被算出…
作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4102743.html 题目链接:hdu 4778 Gems Fight! 博弈+状态dp+搜索 不难发现,无论Alice和Bob以何种方式投掷包裹,他们得到的Magic Stones个数的和$Sum$是一定的,因此只需要计算Alice可以获得的最大的Magic Stones的个数MAXA,则Bob获得的个数为Sum-MAXA,而两者的最大的差为MAXA-(sum-MAXA)为答案.那么如何…
t题意:给你n条边,构造任意个三角形,一个三角形恰好只用3条边,每条边只能一次,求面积最大值 思路: 最开始想的是先排序从大到小取,但感觉并不怎么靠谱. 最多12条边,所以可以求出所有可能的三角形面积,然后就不知道怎么办了- -, 看大神的解法,状态dp,但是没想出来怎么保存状态,ヾ(。`Д´。) 后来发现别人都是用二进制(好吧,没想到),然后dp就行了. #include <iostream> #include <cstring> #include <cstdio>…
这个题目是个挺难表示的状态DP,因为不但要考虑上下还要考虑左右,在DP里面就没有什么下了咯,但也至少除了考虑左右还要考虑上 所以先枚举出在同一行满足条件的状态 即 某状态 若 s&(s<<1) 或者(s&(s<<2)) 则说明同一行的炮塔在射击范围内,要去掉. 然后就是考虑不同行的了,只要上一行和上上行的状态不冲突即可 于是就有了如下状态 dp[i][j][k]代表第i行状态为k,上一行的状态为j时的最大值. 于是它的子状态就是 dp[i-1][w][j]代表上一行…
题意:一个矩形网格,可以填0或1, 但有些位置什么数都不能填,要求相邻两个不同时为1,有多少种填法.矩形大小最大 12*12. 压缩状态DP大多有一个可行的state的范围,先求出这个state范围,对接下来的解题非常有帮助! 注意特判 N==1 的情况. #include <iostream> #include <cmath> #include <cstring> #include <vector> using namespace std; vector&…
原题直通车:HDU  1074  Doing Homework 题意:有n门功课需要完成,每一门功课都有时间期限t.完成需要的时间d,如果完成的时间走出时间限制,就会被减 (d-t)个学分.问:按怎样的顺序做才能使得学分减得最少. 分析:因为n<=15数据比较小,可以用状态DP做.状态k(若k&(1<<j)==1表示第j门功课已经完成,反之未完成), 状态数最多为(1<<16)-1,每个状态k可由状太r(r<k, r&(1<<j)==0且k&…
题意: 一个炮兵可以攻打和他之间曼哈顿距离为2的士兵,给出你一块n*m的战场,告诉你哪些地方可以站人哪些地方不可以,问你最多可以安放多少个士兵? n <= 100, m <= 10 思路: 这道题暴力是不可以的,因为状态太多了 可以状态DP来做,用一个数组G记录战场的限制,然后用一个数组dp[当前状态或者是前一个状态][当前状态的十进制表示][前一个状态的十进制表示] 因为用的是G[1<<m]来表示,所以时间复杂度是n*(2^m)*(2^m)*(2^m),m最多为10,所以时间复杂…
http://hihocoder.com/contest/hiho42/problem/1 给定一个n,问我们3*n的矩阵有多少种覆盖的方法 第41周做的骨牌覆盖是2*n的,状态转移方程是dp[i] = dp[i-1] + dp[i-2],递推数列可以用矩阵快速幂来加速计算 我们可以用状态dp来做这一题,如果某个格子上被铺了骨牌,就标记为1,否则为0 那么每一列一共有8个状态. 两种状态的表示法 第一种: dp[i][s] 表示填满第i行后,第i+1行的状态为s, 那么s的转移情况如下, 0->…
题目大意 一次旅游,经过所有城市至少一次,并且任何一座城市访问的次数不能超过两次,求最小费用 每个城市最多访问两次,用状态0,1,2标识访问次数 把城市1~N的状态按照次序连接在一起,就组成了一个三进制数,所有N个城市的状态都能对应到一个三进制数,对一个状态而言,已经访问的城市不关心它的访问的顺序是怎样的,只要知道到达了这个状态,最后访问是哪一个城市就可以进行转移了, 于是定义状态dp[i][j]标识N个城市处于i的状态,最后一个城市是j所需要的最小费用, 状态转移方程可以是 dp[i+3^i]…
题目链接:https://cn.vjudge.net/contest/269933#problem/H 具体思路:首先,这是一个公平的比赛,并且是两个人参与,两个人都足够聪明,并且可以通过有限步结束比赛,所以可以通过sg函数解决,注意这个题的不同,假设当前的某一堆堆数是5,如果分成每堆为2,他的子状态是2 2 1,和之前做过的子状态不同,之前做的题拿掉的就相当于扔掉了,而这个题并没有. #include<iostream> #include<string> #include<…
思路:状态DP dp[i]=2*dp[i-1]+dp[i-3] 代码如下: 求出循环节部分 1 #include<stdio.h> 2 #define m 10007 3 int p[m]; 4 int main() 5 { 6 p[0]=p[1]=1;p[2]=2; 7 for(int i=3;i<m;i++){ 8 p[i]=2*p[i-1]+p[i-3]; 9 p[i]%=m; 10 } 11 int t,ca=0,n; 12 scanf("%d",&t…
Floyd + 状态DP Watashi的板子 #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int INF = (int) 1e8; <<][]; //dp[S][v] 表示还需访问的集合为S, 现在在v点 ][]; int n; void floyd() { ; k <= n…
题意:外卖员开始在0号节点,有N个人点了外卖,(N<=10),现在告诉两两间距离,问怎么配送,使得每个人的外卖都送外,然后回到0号点的总时间最短,注意,同一个点可以多次经过. 思路:TSP问题(货郎担问题),可以通过状态DP解决小数据问题. 先floyd求一下两两最近距离,然后DP: dp[i][j]表示经过状态为i,当前在j号节点是最小耗时. ans=min(dp[S][i]+dis[i][0]); #include<bits/stdc++.h> #define rep(i,a,b)…
这个题目搁置了这么久,终于搞完了. 给n个人分配n个课程,已经告诉了你n个人对哪几门感兴趣,问最多有多少种分配方式 我刚开始都没找到这怎么还可以状态dp,哪来的状态转移,想用暴力DFS,果断TLE的妥妥的. 后来给殷犇发了这个题目,他还说你刷个这水题还刷得这包子劲,这题目就是后一行的状态由前一行得到,枚举当前这一行分配的状态,如果可行,就从后面的状态加过来 由于状态只是从上一行转移过来,所以可以用滚动数组,用p表示当前,则!p就为上一行的,每次结束再把p置反即可. #include <iostr…
鉴于他的字符串,每一个都能够删除回文子串.子可以是不连续,因此,像更好的模拟压力.求删除整个字符串需要的步骤的最小数量. 最大长度为16,因此不能逐行枚举状态.首先预处理出来全部的的回文子串,然后从第一步開始,依次状压第i步能到达的状态.假设能达到母串,跳出. 还有初始化不要用图省事用memset. . 不优越的姿势+函数导致T了数发. #include <iostream> #include <cstdio> #include <cstring> #include &…
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4628 数据不大,枚举本质.首先对枚举出回文串,然后用DP或者搜索,这里因为层数不多,用bfs比较好,或者用IDA*... //STATUS:C++_AC_140MS_780KB #include <functional> #include <algorithm> #include <iostream> //#include <ext/rope> #include…
题目链接[https://www.oj.swust.edu.cn/problem/show/2480] 题意:中文题目. 题解:二进制状态转移+坏点判断. #include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long LL; << ; LL dp[][maxn]; ]; ]; int n, m; int cur; void DFS(i…
如何学好动态规划(2) 原创 Gene_Liu LeetCode力扣 今天 算法萌新如何学好动态规划(1) https://mp.weixin.qq.com/s/rhyUb7d8IL8UW1IosoE34g 动态规划概述 动态规划(Dynamic Programming),因此常用 DP 指代动态规划.本块内容我们主要讲解「动态规划解题思路」与「动态规划问题类别」. 动态规划解题思路 动态规划主要分为两个核心部分,一是确定「DP 状态」,二是确定「DP 转移方程」. DP 状态 「DP 状态」的…
(1)集合中元素表示(1<<i), i从0开始 (2)注意dp[i][ss] = min(dp[i][ss], dp[i][rr | s[i]] + dp[i][(ss ^ rr) | s[i]]);,后面的要 |s[i],保证状态的正确 (3)INF初始化CLR(dp, 0x3f) (4)注意斯坦纳树状态理解,分层松弛的理解 参考:http://endlesscount.blog.163.com/blog/static/821197872012525113427573/ //#pragma…
这个题目非常赞! 给定一个矩形,要求用1*2 的格子进行覆盖,有多少种覆盖方法呢? dp[i][j] 当状态为j,且第i行已经完全铺满的情况下的种类数有多少种?j中1表示占了,0表示没有被占. 很显然,当每行被放了之后,有一些状态是不可能的,我们这里用1 表示竖着放,0表示横着放. 所以两个0 要相邻,这是程序中的s. 我们每一状态转移,枚举每一个可能的状态,我们希望dp[i][j] 中的j呈现出s[k] 的状态,依次来进行状态转移. #include <iostream> #include…
这个问题要看状态怎么想,第一种直接的想法是1代表未合并,状态就从1111111 转移到 带有1个0,然后带有两个0, 但是这样子编程非常不直观.换一种思路,0代表未合并,但是我可以先合并前几个,就是说在压缩状态的过程中,状态转移的时候尽量是一个连续量的转化 #include <iostream> #include <cmath> #include <cstring> using namespace std; int cost[11][11]; int dp[1<&…
3A的题目,第一次TLE,是因为一次BFS起点到终点状态太多爆掉了时间. 第二次WA,是因为没有枚举蛇的状态. 解体思路: 因为蛇的数目是小于5只的,那就首先枚举是否杀死每只蛇即可. 然后多次BFS,先从起点到第一把钥匙,不能往回走,要用VIS数组标记. 第二次从第一把钥匙走到第二把钥匙. 最后一次从最后一把钥匙走到终点即可. Tips 1: 在每次BFS过程中使用优先队列保证每次是最小步长的状态. Tips2 :使用二进制枚举蛇的状态 Tips3:首先使用DFS判断是否绝对有解,如果无解输出"…
题目 描写叙述 Long , long ago ,country A invented a missile system to destroy the missiles from their enemy . That system can launch only one missile to destroy multiple missiles if the heights of all the missiles form a non-decrease sequence . But recentl…
题目链接[https://www.oj.swust.edu.cn/problem/show/1557] 题意:中文题目. 题解:用0,1表示某个位置是否种了树,先算出同一行的有效状态的总数,即开两个1状态不能相邻的状态. 枚举每一行的状态然后根据行一行的状态判断改状态是否有效,然后对最后一行的所有有效状态求最大值即可. #include<bits/stdc++.h> using namespace std; typedef long long LL; ], k[], N[]; ][]; ];…
题目链接[http://poj.org/problem?id=2411] 题意:给出一个h*w的矩形1<=h,w<=11.用1*2和2*1的小矩形去填满这个h*w的矩形,问有多少种方法? 题解:第一步把第0行全部置1,达到这种状态的方案数是1.然后对于r排,根据r-1排的状态处理r排的状态.如果r-1排的pos位置为0,即没有没木块占用,那么r排的pos位置必须竖着放木块. 总的来说是,在处理r排的时候,要先把r-1排填满,然后剩下的位置就随意填(用DFS实现).dp[i][j]表示:到达的i…
Give a string s, count the number of non-empty (contiguous) substrings that have the same number of 0's and 1's, and all the 0's and all the 1's in these substrings are grouped consecutively. Substrings that occur multiple times are counted the numbe…