自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

Neutralzz的博客

我有自己的梦想和追求!

  • 博客(227)
  • 收藏
  • 关注

原创 HDU 4352 XHXJ's LIS (数位DP+状态压缩)

最长递增子序列很自然就想到二分(nlogn)的算法,用状态S存储二分后的答案,第i位为1就是i存在于二分的答案中。注意前导0。我的代码:#include#include#include#includeusing namespace std;typedef __int64 LL;const int inf = 0x3f3f3f3f;LL dp[20][1<<10][11

2015-07-22 15:38:47 264

原创 CodeForces 55D Beautiful numbers (数位DP)

题意:一个数字,如果它能被所有的非零数字整除,就为 Beautiful numbers。参考题解:点击打开链接dp[位数][高位数字模2520的余数][最小公倍数]AC代码:#include#include#include#includeusing namespace std;typedef __int64 LL;LL c[2550],g[2550][10]

2015-07-22 15:27:53 332

原创 HDU 4734 F(x) (数位DP)

题意:我们定义十进制数x的权值为f(x) = a(n)*2^(n-1)+a(n-1)*2(n-2)+...a(2)*2+a(1)*1,a(i)表示十进制数x中第i位的数字。题目给出a,b,求出[0,b]有多少个不大于f(a)的数。我理解的数位DP就是通过按位记忆化搜索找出所有满足条件的小于等于n的数。然后对于第i位,状态s是由其高位确定的。数位DP的题目一般都很明显,关键在于状态的设计。看

2015-07-21 23:00:40 255

原创 POJ 3140 Contestants Division (水题)

思路:记录每个节点的子节点的总和和非子节点的总和的差的绝对值,再扫一遍就完了。水题。。。和树形DP没关系。。。代码:#include#include#include#include#define abs(x) ((x) >= 0 ? (x) : -(x))using namespace std;typedef __int64 LL;const LL maxn = 1000

2015-07-19 12:00:05 267

原创 POJ 3107 Godfather (水题,树形DP)

思路:设dp[i]为在i的子树中,删去i后的最大连通子图的顶点个数。dp[u] = max(dp[u],num[v])。代码:#include#include#include#includeusing namespace std;const int maxn = 50005;const int INF = 1e6+5;struct Nod{ int b

2015-07-19 11:53:15 284

原创 HDU 3586 Information Disturbing (树形DP+二分)

思路:二分上限,求出删去一些满足条件的边后使根节点和所有叶节点不相连的最小花费。设dp[i]为在i为根节点的子树中使i节点与叶节点分离的最小花费。父节点为u,子节点为v,边权为cost。初值:叶节点值为INF。如果cost反之,dp[u] += dp[v]。代码:#include#include#include#includeusing namespa

2015-07-19 11:39:28 243

原创 ZOJ 3627 Treasure Hunt II (贪心)

水题,不过细节坑死,WA了很多发。。。思路:先从起点不断往两侧走,左端边界lb为max(1LL,p-t),右端边界为min(n,p+t)。如果rb-lb 反之,如果M是偶数,就让两个人从起点分别走M/2步,往后就是先向左再向右还是先向右再向左的问题,枚举就好了。如果M是奇数,两个人中其中一人要走M/2+1步,同样枚举即可。代码:#include#inclu

2015-07-19 11:07:56 315

原创 HDU 1561 The more, The Better (树形DP+背包)

思路:设dp[i][j]为在以i为根节点的子树中在i节点处还可以访问j个节点的最大收益。那么初始状态:j>=1时,dp[i][j] = val[i]dp[u][j] = max(dp[u][j],dp[u][j-k]+dp[v][k])需要注意的是,要想访问v节点,u节点必须被攻克,所以k的范围是1到j-1。代码: #include #include #incl

2015-07-19 10:52:31 245

原创 HDU 1011 Starship Troopers (树形DP+背包)

思路:设dp[i][j]为以i为根节点的子树中在i点还有j个troopers的最大收益。初值需要注意,dp[i][0]必须为0,因为你要获得i中的brain必须要放至少一个trooper。在循环中让k从1开始取可以达到同样的效果。转移方程:dp[u][j] = max(dp[u][j],dp[u][j-k]+dp[v][k]);代码:/* * dp[u][j] = m

2015-07-19 10:42:49 243

原创 POJ 1947 Rebuilding Roads (树形DP)

思路:设dp[i][j]为以i为根节点的子树中,形成j个节点(包含i)的子树需要切断的最少路数。那么初值dp[i][0] = 1,dp[i][1] = 0;dp[u][j] = min(dp[u][j-k]+dp[v][k],dp[u][j])。代码:#include#include#includeusing namespace std;const int max

2015-07-19 10:28:44 179

原创 POJ 1155 TELE (树形DP+背包)

思路:设dp[i][j]为在以i为根节点的子树中,连接j个用户的最大收益。u为父节点,v为子节点,那么dp[u][j] = max(dp[u][j],dp[u][j-k]+dp[v][k]+cost)。实现过程注意加上break,不然容易T。。。代码:#include#include#include#includeusing namespace std;co

2015-07-19 10:17:51 267

原创 CodeForces 219D Choosing Capital for Treeland (树形DP)

思路:dp[i]为在以i为根节点的子树中i到各点的需要反向的路的数目。那么dp[u] = sigma(dp[v] + i) 如果(u,v)是反向边,i=1;反之为0。这样求出的dp[u]为u到其子树各点的反向边的数目。在做一遍dfs,使dp[v] = dp[u] + i 如果(u,v)是反向边 ,i=-1;反之,i=1。代码:#include#include#inc

2015-07-19 10:01:50 354

原创 POJ 3162 Walking Race (树形DP)

这个题的关键点在于怎么求出上下界思路:先像上一篇一样求出每个点到达的最大距离,用mlen[]记录下来。然后用multiset去维护区间的最大值和最小值,因为multiset是升序的。复杂度O(nlogn)我的代码:#include#include#include#include#includeusing namespace std;const int ma

2015-07-17 13:03:04 240

转载 HDU 2196 Computer (经典树形DP)

本文出自点击打开链接本人代码:#include#include#include#includeusing namespace std;const int maxn = 100005;struct Nod{ int b,val,next; void init(int b,int val,int next){ this->b = b;this->

2015-07-17 08:49:04 268

原创 HDU 2196 Anniversary party (树形DP 水题)

题意:一个森林,每个节点都有一个值,每个节点和他的父节点不能同时出现,求出现的节点的值的和的最大值。思路:dp[i][j] 为以i为根节点的树的最大值的和,j = 0说明根节点存在,j =1说明不存在。我的代码:#include#include#include#includeusing namespace std;const int maxn = 6005;int n,

2015-07-16 22:29:07 237

原创 HDU 4745 Two Rabbits (区间DP)

题意:n个石头排成一个环,每个环有自己的重量,两只兔子从两个石头上出发,每一轮从一个石头跳到另一个石头,一个顺时针,一个逆时针,并且同一时间两只兔子所在的石头重量相等。每只兔子不能跳到并且跳过自己曾在的石头。问最多进行多少轮。思路:把n个石头排成一排,再取n个石头和前n个石头一样,成2n个石头。比如说1121变成11211121然后把这2*n个石头排成一个环,求这个环内的最长回文子串的

2015-07-16 18:33:47 248

原创 HDU 4632 Palindrome subsequence(区间DP 回文子串的个数)

题意略。思路:设dp[i][j] 为i到j内回文子串的个数。那么状态转移方程为dp[i][j] = dp[i][j-1] + dp[i+1][j] - dp[i+1][j-1]如果a[i] = a[j] ,dp[i][j] += (dp[i+1][j-1] + 1)。我的代码:#include#include#includeusing namespace std

2015-07-16 18:06:43 1872

原创 UVA 10892 LCM Cardinality (因子分解 水题)

题意:求有多少对(a,b) 使lcm(a,b) = n。思路:对n因子分解,暴力枚举。代码:#include#includeusing namespace std;typedef long long LL;LL n,top,a[10005];LL gcd(LL a,LL b){ return b != 0 ? gcd(b,a%b) : a;}LL lcm(

2015-07-16 17:57:23 348

原创 UVA 10891 Game of Sum (区间DP)

题意:有n个数,两个玩家A、B,每个玩家在他那一轮可以从左端或右端取连续的一段数,把数的和加到自己的分数上,假设每个玩家都采取尽可能的让自己的分数更高,那么A玩家最后和B玩家分数的差为多少(A玩家先手)思路:设dp[i][j][0]为自己先手在区间i到j内最后获得的最多的分数dp[i][j][1] 为对方先手在区间i到j内最后获得的最多的分数那么状态转移方程:dp[i][j][

2015-07-16 17:52:16 264

原创 UVA 10688 The Poor Giant (区间DP)

题意:有n个苹果,第i个苹果的重量为k+i。其中只有i个苹果是甜的,比它轻的苦,比它重的酸,Giant想要找到甜苹果,必须要通过吃掉某个苹果然后判断甜苹果的位置,吃苹果的时候必须全部吃掉。问在找到甜苹果的过程中的所有情况吃掉苹果重量的最小值。例如:n = 4 , k = 0.Gaint先吃第2个。如果第2个是甜的,那么甜苹果是2如果第2个酸,那么甜苹果是1如果第2个苦,再吃第3个就

2015-07-16 16:47:25 283

原创 POJ 3186 Treats for the Cows (区间DP 水题)

题意略。思路:设dp[i][j]为买出i到j的最大收益。状态转移方程:dp[i][j] = max(dp[i+1][j] + a[i]*(n - j + i) , dp[i][j-1] + a[j]*(n - j + i));我的代码:#include#include#includeusing namespace std;const int maxn = 2005;

2015-07-16 16:38:29 271

原创 ZOJ 3735 Josephina and RPG (概率DP)

题意:有r个角色,i角色打败j角色的概率为p[i][j].游戏有n轮,每轮都会有一个角色与你对战,游戏开始你可以选择一个角色进行游戏,每轮结束后如果你胜出,可以进行下一轮,并且可以把自己使用的角色更换为刚打败的角色,求通关的最大胜率。思路:设dp[i][j]为在第i轮用j角色通关的最大概率状态转移方程:dp[i][j] = p[j][a[i]] * max(dp[i+1][j],dp[

2015-07-16 16:29:03 633 1

原创 LightOJ 1422 Halloween Costumes (区间DP)

题意:Gappu有N个聚会要去参加,每个聚会需要穿第ci件服装,每到一场聚会,Gappu可以在现在穿的衣服上再套上需要穿的服装,如果里层穿有需要的服装,也可以选择脱去外层的服装直到那件需要的,脱掉了的衣服不能再穿,问最后至少需要多少件服装。思路:设dp[i][j] 为区间i到j至少需要的服装数。状态转移方程:dp[i][j] = dp[i+1][j] + 1;dp[i][j]

2015-07-16 16:16:43 231

原创 POJ 2955 Brackets (区间DP 经典括号配对)

题意略。思路:设dp[i][j]为区间i到j的regular brackers的最大长度。状态转移方程:如果a[i]和a[j]配对,那么dp[i][j] = dp[i+1][j-1] + 2;dp[i][j] = max(dp[i][j],dp[i][k] + dp[k+1][j]);我的代码:#include#include#includeusing

2015-07-16 15:14:55 381

原创 POJ 1651 Multiplication Puzzle(区间DP 水题)

题意很短略去不说了。思路:设dp[i][j] 为区间i到j的最大分数。状态转移方程:dp[i][j] = max(dp[i][j] , dp[i][k-1] + dp[k+1][j] + a[k]*a[i-1]*a[j+1]);我的代码:#include#include#includeusing namespace std;const int maxn =

2015-07-16 15:04:47 346

原创 ZOJ 3469 Food Delivery (区间DP)

题意:在x坐标轴上,饭店位置是X,需要送餐的n个地点位置在Xi,每个地点每多等一分钟,不满意度会增加Bi,求给所有的地点送完餐后的最小不满意度的和。思路:先对各个地点按x从小到大排序。用sum[i]来存取0到i每等一分钟累计不满意度的和。设dp[i][j][0]为给区间i到j的送完餐且最后到达i后累计的不满意度的和,dp[i][j][1]为给区间i到j的送完餐且最后到达j后累计

2015-07-16 14:45:49 257

原创 HDU 2476 String painter (区间DP)

题意:两个字符串A,B,一次操作可以把一段字符改为任意的相同字符,问把A改为B的最小操作次数。这是我第一个区间DP,参考题解:点击打开链接思路:这题实际上是两个DP。一、第一个dp是求出把空字符串变为字符串B 的最小操作次数。设dp[i][j] 为把空字符串i到j变为对应的字符串B的最小操作次数。那么就有dp[i][i] = 1;状态转移方程为:dp[i][j] = min

2015-07-13 22:12:39 271

原创 HDU 4089 Activation (概率DP 好题)

做DP题关键的第一步就是确定状态,上来状态错了,这题百分之八九十就没法做了,其实就那几个关键的变量,我上来一般是凭直觉确定状态,卡住了的话,取一两个变量代入试试咯。这个题一开始状态的确定卡了一下。。。思路:设dp[i][j] 为i个人,Tomato 在第j个位置时达到目标状态的概率。那么j的取值要分为三种情况。dp[i][1] = p[1]*dp[i][1] + p[2]*dp[i

2015-07-13 10:25:18 381

原创 HDU 4336 Card Collector (状压+概率DP)

题意很短略去不说。思路:设dp[S] 为已集齐状态S中的各卡片后集齐所有卡片的期望值。那么方程为dp[S] = 1 + sigma(dp[S + {v}] *p[v]) + (1 - sigma(p[v]))*dp[S]  (v是S中不包含的状态)代码:#include#includeusing namespace std;const int MAX = 20000

2015-07-12 23:16:51 323

原创 HDU 4035 Maze (很好的概率DP)

做了有些概率和期望的题目了,现在觉得大致有那么两种办法。【说白了还是要靠数学一、直接利用组合计数求解。二、通过状态转移列出方程来,如果能递推就直接DP,不能的话,通过对式子处理,找出式子之间的关系和结构上的特点,通过待定系数来进行迭代,最后求出结果。。。。再有的话就是用容斥啊状压啊什么的【估计自己也不一定想得到言归正传来说题吧,我把自己的思路写在注释里了。参考题解:点击

2015-07-12 21:55:09 279

原创 ZOJ 3380 Patchouli's Spell Cards( 概率DP)

题意:用n个数填充m个位置,问有大于等于l个相同数字的概率。这个题看了很多题解,大部分代码都是有点问题的,一开始dp的状态都是一样的。(具体见下)思路:设dp[i][j] 为用前i个数填充j个位置的方案数。则dp[i][j] = sigma(dp[i-1][j-k] * C[m-j+k][k]) (k >= 0 && k 最后的结果应该是(n^m - dp[n][m]) /  n^

2015-07-12 16:29:11 304

原创 HDU 4418 Time travel (高斯消元求期望) 好题

这题上来就没读懂题。。。。。。题意:一个人在数轴上向左或向右走,走到头就改变方向,每次走,走i步的概率为Pi。求从起点到终点的步数的期望。思路:这个题的关键一步在于把向左和向右这两个起初状态变为一个状态。做法是把原先n个位置变成2*n-2个位置。举例:01234   ------> 01234321 这样 如果开始是从2向左走,就等价于从第7个位置开始往右走。这样需要注意终点可能会

2015-07-12 00:27:01 415

原创 ZOJ 3640 Help Me Escape (概率DP)

题意很好理解,略去不说了。思路:设dp[i]为战斗力为i时走出洞穴的期望。先对c[]从小到大排序。再二分查找c>=i的位置。那么期望逆推得 dp[i] = (t1 + t2 + ......tk-1 + dp[i+ck] + 1 + ..... dp[i+cn] + 1) / n。我的代码:#include#include#include#include#i

2015-07-12 00:18:40 318

原创 POJ 3071 Football (很好的一个概率DP)

题意:1...2^n个队伍比赛,每一轮所有的队伍按照顺序两两比赛。比如说第一轮就是1对2,3对4。给出一个矩阵P= [pij] ,pij表示i队打败j队的概率。求最后哪个队伍最有可能拿冠军。思路:设dp[i][j] 为在第i轮中j胜出的概率。那么dp[i][j]  = sigma(dp[i-1][k]*p[j][k]) k是在第i轮中所有有可能与j对战的队伍。问题的关键是怎么找出k。

2015-07-12 00:05:17 265

原创 HDU 2151 Worm (记忆化搜索) 水题

题意略。思路:设dp[i][j]为当前位置为i,剩余时间为j到达终点的方案数。dp[T][0] = 0;dp[i][j] = dp[i-1][j-1] + dp[i+1][j-1]。我的代码:#include#include#includeusing namespace std;const int maxn = 105;int n,p,m,t;int d

2015-07-11 23:54:40 335

原创 HDU 3853 LOOPS (概率DP水题)

题意略去不说。思路: 设dp[i][j] 为从(i,j)出发到终点的期望值。方程:dp[i][j] = 2 + p[i][j][[0]*dp[i][j] + p[i][j][[1]*dp[i][j+1] + p[i][j][[2]*dp[i+1][j] 。(注意p[i][j][0] = 1时 dp[i][j] = INF)我的代码:#include#include#

2015-07-11 23:49:29 464

原创 HDU 4341 Gold miner (分组背包)

题意:每个金子有自己的位置,得到所用的时间和价值。要想得到某个金子,必须先得到从原点到目标连线的所有金子。求给出时间内获得的最大价值。思路:把在同一直线的金子视为一组,对于每个金子,把原点到目标的所有的金子的时间和价值都加到目标上,然后分组背包就不必多说了。我的代码:#include#include#include#include#includeusing na

2015-07-11 23:39:07 247

原创 ZOJ 3329 One Person Game (概率DP)

题意:三个多面体,面数分别为K1,K2,K3。每个面标号1,2,...,K。投掷一次,如果是a,b,c,那么把计数器设为0,反之,计数器加上(a + b + c)。如果计数器大于n,游戏结束,反之继续投掷。求投掷次数的期望值。思路:设dp[x]为从计数器为x时开始投掷,投掷到>n的期望值。那么方程为dp[x] = 1 + dp[0] / k1 / k2 / k3  + sigma(dp[x

2015-07-11 12:12:04 227

原创 POJ 2096 Collecting Bugs (概率DP入门)

今天看了kuangbin博客里的概率DP总结http://www.cnblogs.com/kuangbin/archive/2012/10/02/2710606.html开始的一句话感觉很有道理(概率正推,期望逆推)【不过谁能给我详细讲一下,现在只是感觉上很有道理设dp[i][j]为已找到i种bug和j个subconponent后到达目标的期望。那么dp[i][j] 可以转化成

2015-07-10 23:32:01 312

原创 POJ 3744 Scout YYF I(概率DP+数学)

不考虑地雷,设f[i]为在i位置上的概率。有f[i] = p * f[i-1] + (1 - p) * f[i-2]。考虑地雷的话分段算就好了,然而这个问题的关键在于怎么求这个f[i]。开始看见这个用的矩阵快速幂,,,结果T了【话说别人也有这样做没T的,但看了半天不知道怎么优化所以就打算求f[i]通项【就是靠数学咯算出来f[n] = f[1] * (1 - (p - 1)^

2015-07-10 09:13:21 693 2

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除