自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(32)
  • 收藏
  • 关注

原创 AOJ 2249

优先队列+Dijkstra 因为题目中所给的点的个数多达10000个,而且看得出来要求最短路,但是普通的Dijkstra的效率为O(n^2),这显然是不行的,那么我们可以用优先队列+DIjkstra。题目中说了,要求去掉一些边,使得总花费最少,但是去掉边后不能影响从源点到其他所有点的最短路。那么与普通的相比,就是当dis[v] == dis[u] + r [u] [v]时是cost[v]小还是co

2015-09-30 23:24:17 385

原创 Aoj 2170

简单的并查集应用。 不过注意,我们平常用的路径压缩在这里就不能用了,因为我们并不更新路上的所有结点到同一个并查集中去,这里只是做查询的用途。 题目中当mark一个点时,我们就用fa[x]=x去更新某个点,使它作为一个并查集的根节点,然后如果要查询离x最近的mark点,那么我们就逐渐网上找,找到第一个fa[x]=x的点,然后返回它的值,注意,这过程中我们不能进行路径压缩。#include<stdi

2015-09-29 14:09:48 513

原创 poj 1330

LCA裸题。 这里我用tarjan(dfs+并查集)的方法进行离线处理。 这是第一个例子的图,题目中求的是16和7的LCA,那么这个过程是这样的。 我们从根节点,即8号开始搜索,每次计算完LCA(u)以后,那么我们就处理了以u为根节点的子树,比如我们计算了4,6,15,7那么这棵子树就为一个集合,然后它们的根节点为4,然后再从4往右边走,当我们走到16时,发现7已经被处理过了,说明此时它们

2015-09-17 20:38:12 257

原创 poj 1703

经典的并查集问题。 我们可以有两种做法: 第一种是我们用一个数组vis[i]=j来表示i的敌人是j,那么我们在知道a,b是敌人之后,那么如果vis[a]有值的话,vis[a]和b是一伙的,如果vis[b]的有值的话,vis[b]和a是一伙的。所以这样判断即可。#include<stdio.h>#include<iostream>#include<string>#include<string

2015-09-17 19:14:06 277

原创 poj 2236

并查集应用的简单题。对于每一个修好的电脑,我们遍历所有已经修好的电脑,如果它们之间的距离小于等于d,那么我们就将两个集合合并到一起,在询问是否能够互通时,就看它们是否属于同一个集合,但是我们不能写成fa[x] == fa[y],而应该写成find(x)==find(y),因为有可能有些节点并没有进行路径压缩,进而也没有在同一个集合中,所以我们得再压缩一下。#include<stdio.h>#inc

2015-09-17 18:25:59 302

原创 poj 2010

这道题目刚开始还真不好想,看了别人的解题思路之后恍然大悟,思路太棒了~ 题目大意是给你三个值,N,C,F,C代表有C头牛,N为奇数,代表要在C头牛中选择N头牛,每头牛有两个值,分数和代价,使得被选中的N头牛的中位数尽量大,并且它们的代价和不能超过C。 刚开始将所有的牛按照分数大小排序,然后我们用lower[i]来表示前i头牛中(不包括第i头牛)代价和最小的N/2头牛的总代价和,那么我们从头开始扫

2015-09-17 10:22:12 370

原创 poj 3614

优先队列求解。 将防晒霜按值从小到大排序,将蚂蚁的最小忍耐值按从小到大排序,然后对于每个防晒霜,如果该蚂蚁的最小忍耐值小于等于它的值,那么就把该蚂蚁的最大忍耐值放入优先队列,该优先队列的规则是将小的数放前面,也就是我们取那个最小且符合题意的忍耐值。#include<stdio.h>#include<iostream>#include<string>#include<string.h>#in

2015-09-16 21:59:05 357

原创 poj 2184

一道01背包的变形题。 从题目描述中我们可以看出,对于一头牛,我们可以选或者不选,所以这是一个01背包的雏形。然后每头牛有两个值,一个是s,一个是f,我们可以将其中一个当做cost,一个当做weight,那么对应的一个就是dp[i],一个是i,这样全部求出来以后,我们在全部dp[i]>0的情况中寻找dp[i]+i最大的那个即可。 这道题目还有负数的情况,那么我们可以将背包的容量进行一个偏移,题目

2015-09-16 16:01:00 273

原创 poj 2392

多重背包问题,这里还要先排序一下,要把限高高度小的放前面,这样子才能将所有的电梯都充分利用起来,如果把高度小的放后面就会造成无法利用。 这里对于每个电梯来说,它们的背包上限就是它们的限高高度。#include<stdio.h>#include<iostream>#include<string>#include<string.h>#include<algorithm>#include<i

2015-09-16 11:43:48 390

原创 poj 3666

dp真的要多做才能有门路啊! 我们用dp[i][j]来表示前i个数来表示结尾是整个序列中第j大小的总的代价。 还有一个前提我们是要知道的,就是我们虽然说是修改序列中的某几项使得它成为一个有序序列,但是改完后的数字肯定是序列中本身就存在的,不会修改出一个新的数字来。 比如有三个数a,b,c 假设a#include<stdio.h>#include<iostream>#include<str

2015-09-16 10:43:07 372

原创 poj 5444

这题。。其实我对树这玩意还是有点恐惧的。。(:зゝ∠) 直接模拟不就好了!#include<stdio.h>#include<iostream>#include<string>#include<string.h>#include<algorithm>#include<iomanip>#include<vector>#include<time.h>#include<queue>#i

2015-09-14 22:25:26 288

原创 hdu 5441

这道题目是用并查集来维护联通点的个数。 我们首先将所有路径按权值大小从小到大排序,然后将所有询问也按权值从小到大排序(没错,我们要离线处理),接着遍历一遍询问,将符合条件的路径两端点合并,我们用rk[i]来代表i点所在并查集的大小,假设两个端点分别为u,v,那么它们所在并查集大小为rk[u],rk[v],则当这两个点合并以后,这两个并查集中的点就合并起来了,根据题意,多出来的数目为rk[u]*rk

2015-09-14 21:44:10 369

原创 CF #319 B Modulo Sum

这是一道不错的dp题。 我们用dp[i][j]来代表前j个数能够达到的对m取余的余数,而我们发现j只与j-1有关,可以用滚动数组。那么我们只需要用类似背包的dp来计算出所有可能的结果即可。#include<stdio.h>#include<iostream>#include<string>#include<string.h>#include<algorithm>#include<ioma

2015-09-13 22:55:11 423

原创 poj 3181

仔细观察,其实这是一道完全背包的问题,因为每种货币的数量是不受限制的。 然后我们来推测下转移方程 dp[i][j]代表用前j种货币来组成面值为i的方法总数,那么 dp[i][j] = dp[i][j-1]+dp[i-j][j-1],即组成面值为i的可以不用到第j种货币(dp[i][j-1]),也可用到第j种货币(dp[i-j][j-1]),而我们可以发现,它的第二维都为j-1,那么想到背包的知

2015-09-10 22:59:32 367

原创 poj 3046

我们用dp[i][j]来代表前i种蚂蚁所能组成规模为j 的蚁群的方法数,那么转移方程应该是 dp[i][j] = (dp[i][j]+dp[i-1][j-k]) 0<=k< N[i] N[i]为第i种蚂蚁的个数,用文字来说,就是前i种蚂蚁组成规模为j的蚁群方法数是由 前i-1种蚂蚁组成j-k种转移过来的,至于j,它为当前蚁群的总数。 而i为1000,j最大为100000,直接开会MLE,我们观

2015-09-10 20:58:38 258

原创 poj 1742

这是一道多重背包的题目。 我们可以用多重背包的可行性来对题目进行求解。#include<stdio.h>#include<iostream>#include<string>#include<string.h>#include<algorithm>#include<iomanip>#include<vector>#include<time.h>#include<queue>#inc

2015-09-10 16:55:32 270

原创 poj 3280

这道题目名义上赋予了每个字母给了两个值,删除的代价和增加的代价,但是其实只有代价小的有用。理由很简单,对于一个非回文子串来说,增加一个字母和删除一个字母是等价的,比如abb,我们可以发现,有这么两种操作,第一种是将开头的a删除,第二种是在末尾加个a,至于使用哪个,就看删除和增添哪个代价小了,所以说删除和增添是等价的,我们只要留下那个代价小的即可,无需关心到底是删除还是增加。 我们用dp[i][j]

2015-09-09 20:32:53 304

原创 poj 3616

比较简单的dp。 转移方程是: dp[i] = Max(dp[i],dp[j]+a[i].ef) //0<=j< i,条件是a[i].st>=a[j].ed#include<stdio.h>#include<iostream>#include<string>#include<string.h>#include<algorithm>#include<iomanip>#include<v

2015-09-09 17:15:26 286

原创 poj 2385

这道题目是一道经典的dp题。 我们用数组dp[i][j]来表示前i分钟最多走j步所能够接到的最多的苹果,首先处理边界,然后注意走到第i分钟时我们身处的苹果树编号,如果是走了偶数步,那么我们回到了1号树,如果走了奇数步,那么我们走到了2号树。 状态转移方程为 dp[i][j] = Max(dp[i-1][j],dp[i-1][j-1]).即我们在第i-1分钟时要么不走,要么走,就这么两种选择。#i

2015-09-09 16:12:15 256

原创 poj 2229

这道题目属于比较典型的递推。 如果一个数i是奇数,我们可以发现,它的组合方法跟i-1肯定是一样的,就相当于在每个i-1方法的后面+1,就可以组合为i. 如果一个数i是偶数,我们就得分类: 1.如果组合方法中有1,那么肯定有偶数个1,也就是我们在i-2的后面+1+1,形成了i. 2.如果组合方法中没有1,那么全部都是偶数,我们只需将所有i/2的组合方法全部*2即可。 举个例子: 比如4,那

2015-09-09 15:04:16 253

原创 poj 3176

‘金字塔’形的基础dp题 选择一条从上到下的路,使得走过的总权值最大。 我们从下往上dp,每次挑选一个下一行大的与上面一行相加。#include<stdio.h>#include<iostream>#include<string>#include<string.h>#include<algorithm>#include<iomanip>#include<vector>#includ

2015-09-09 13:52:38 186

原创 poj 3262

这道题目直接被猜中了贪心的策略= =。就是对于每只羊的t,d如果d/t越大,那么就应该先被送回羊圈。证明的话比较复杂一点,discuss里面有。#include<stdio.h>#include<iostream>#include<string>#include<string.h>#include<algorithm>#include<iomanip>#include<vector>#

2015-09-09 13:14:59 346

原创 poj 1862

此题理解了就很简单。对于一个重量为m1,m2的stripies,它们相遇后产生一个新的重量为2*sqrt(m1*m2)的stripies,那么我们的贪心策略就是每次挑选两个质量最大的stripies来“相遇”,因为我们可以看出来,越早挑选的stripies,它在之后所经历的开方层数越多(因为它不断遇到新的stripies,那么计算更新的stripies时,它就要经历新的开方),那么如果大的能够早点产

2015-09-08 22:45:48 338

原创 poj 3040

这个题目挺难想的,,就算知道怎么做,都不太好写。。 思路是这样的:一共有n种货币,我们已知每种货币的面值v和数量b,我们也知道每周至少要支付c。那么如果有某种货币的面值超过c,那么这种货币就可以直接支付b个星期,然后将其数量置为0. 对于另外的货币,我们按照面值从大到小先每个拿尽量多的,只要不超过c.如果没有拿够c,那么我们就从小到大的拿,而且一张一张拿,拿到直到c,然后计算所有使用过的货币所能

2015-09-08 21:30:50 382

原创 poj 1017

模拟题,我们按照先放体积大的,再放体积小的贪心思想来放,就能够使得盒子总数最少,具体看注释。#include<stdio.h>#include<iostream>#include<string>#include<string.h>#include<algorithm>#include<iomanip>#include<vector>#include<time.h>#include<q

2015-09-08 16:55:02 227

原创 poj 2393

贪心思想。对于第i周,我们取的价格要么是本周的,要么是前几周生产费用+存储费用。更新下每周的价格以后就可以计算总的最小的花费。#include<stdio.h>#include<iostream>#include<string>#include<string.h>#include<algorithm>#include<iomanip>#include<vector>#include<t

2015-09-08 15:36:01 303

原创 poj 3190

仍然是区间的贪心问题。 贪心策略是这样的:我们首先将所有的牛按照区间A-B的A从小到大排序,然后用优先队列维护这个区间,排列规则是按照B从小到大排序,对于第i头牛,如果它的A大于此时最小的B,那么说明它们可以在同一个牛棚,它们的编号就是相同的。否则,就新开一个牛棚。#include<stdio.h>#include<iostream>#include<string>#include<stri

2015-09-08 14:44:13 309

原创 poj2376

区间覆盖问题,思想比较简单,就是贪心,刚开始我们选一个由1开始覆盖最长的区间1-x,那么接下去我们就选左边界<=x+1,右边界最大的那个即可。 实现起来不难,但是坑点比较多。 1.[1,2]&[3,5]是可以覆盖1-5这个区间的,所以第i个区间的左边界只要<=第i-1个区间左边界+1即可。 2.当已经全部覆盖的时候,要及时跳出循环。#include<stdio.h>#include<iost

2015-09-08 11:00:49 305

原创 Aoj0525

题目大意是给你一个n*m的01矩阵,0代表面朝下,1代表面朝上,现在选择其中几个将它翻过来,翻的时候要同时翻动其所在的行 或者 列,问最多能够有几个位置上的值为1。 这道题目学到了一个新的东西,叫做bitset,它可以存储数据,并能灵活操作数据中的每一个位。 首先,我们用bitset<>a[]来new一个二维的”数组”,然后我们知道,此题行比较少,所以我们对行进行操作,对于行x,如果想将其所有的

2015-09-06 10:48:35 335

原创 poj2718

源链接:http://poj.org/problem?id=2718 此题数据不大,最简单的做法就是直接用next_permutation来对原数组进行排列组合,我们知道,如果要使两个和最小,那么它们的长度肯定差不多,所以我们就对排列后的数组进行分割(注意原数组长度的奇偶性)。 这道题目有几个要注意的地方: 1.就是输入的格式问题,我们输入的时候每一个case,是以’\n’结尾,而最后一个ca

2015-09-05 10:41:45 372

原创 CF #318(Div2)

A:枚举1号的得票数,对于得票数x,2-n号大于x一定得减小到x-1,其它的可减可不减。#include<stdio.h>#include<iostream>#include<string>#include<string.h>#include<algorithm>#include<iomanip>#include<vector>#include<time.h>#include<que

2015-09-02 17:48:07 248

原创 CF #316(Div2)

A:水题,读懂题意就不难了。#include<stdio.h>#include<iostream>#include<string>#include<string.h>#include<algorithm>#include<iomanip>#include<vector>#include<time.h>#include<queue>#include<stack>#include<i

2015-09-02 11:26:49 259

空空如也

空空如也

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

TA关注的人

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