09 2012 档案

摘要:题意:给一棵树,问最少砍断多少条边才能产生一个恰含m个结点的子树。分析:将树有根化后,我们考虑以 i 为根结点的子树,要在这棵子树内产生一个结点数目为 j 的子树,要么包含结点 i ,要么不包含,所以定义 dp[i][j][0]表示从以结点 i 为根的子树中得到恰含 j 个节点且不含结点 i 的子树最少需要砍掉的边数,dp[i][j][1]表示从以结点 i 为根的子树中得到恰含 j 个节点且包含结点 i 的子树最少需要砍掉的边数。初始化:树DP中的初始化其实可以把所有结点都看成是叶子结点来处理,dp[i][0][0]=0,dp[i][1][1]=0,其余的全初始化为INF状态转移:dp[a][ 阅读全文
posted @ 2012-09-22 09:42 BeatLJ 阅读(271) 评论(0) 推荐(0)
摘要:题意:现有一棵苹果树,树中每个结点上都有一定数量的苹果,问若从根结点出发,最多只能走K步(每一步都只能从一个结点走到相邻结点),最多能摘多少苹果。分析:定义dp[i][j][0],表示从 i 出发,向下走 j 步,最后回到 i 最多能摘的苹果数,dp[i][j][1]表示从 i 出发,向下走 j 步最后没有回到 i 最多能摘多少苹果。View Code #include <stdio.h>#include <string.h>#include <algorithm>using namespace std;#define N 101int n,e,step,w 阅读全文
posted @ 2012-09-20 17:10 BeatLJ 阅读(208) 评论(0) 推荐(0)
摘要:题意:对一棵树,求出从每个结点出发能到走的最长距离(每个结点最多只能经过一次),将这些距离按排成一个数组得到d[1],d[2],d[3]……d[n] ,在数列的d中求一个最长的区间,使得区间中的最大值与最小值的差不超过m。分析:用2次dfs能求出树的直径,对于树中任意结点,到树的直径的2个端点的距离的较大者即为最长距离。得到数组d后,用2个单调队列分别维护最大与最小值,扫描d数组,同时更新答案。View Code #include <stdio.h>#include <string.h>#include <algorithm>using namespace 阅读全文
posted @ 2012-09-20 16:58 BeatLJ 阅读(700) 评论(0) 推荐(0)
摘要:题意:一个电视网络要转播一场比赛,电视网络的拓扑结构是一棵树,树根是总站,叶子结点都是用户,树边权为信号通过此边的费用,转播总费用为信号通过的所有边的权和,现已知每个用户愿意交付的费用,问电视台在不亏本的情况下最多能为多少用户转播比赛。分析:定义dp[i][j]为从结点 i 往下给 j 个用户转播比赛的最大利润,最后的答案就是使 dp[1][j] 非负的最大的j,可以二分求解。dfs里面那个 j 循环需要根据叶子结点的数目进行优化,否则会TLEView Code #include <stdio.h>#include <string.h>#include <algo 阅读全文
posted @ 2012-09-18 17:30 BeatLJ 阅读(321) 评论(0) 推荐(0)
摘要:题意:从时间0开始需要接待n个人,对于每个人,可以选择接待或者跳过,若接待,花费的时间是T+ai ,T为开始接待这个人的时间,若跳过则罚时bi ,现给定总时间K,问你最多能接待多少人?分析:如果接待的人的集合确定了,那你一定先接待 bi 小的人再接待 bi 大的人,所以我们可以先按 b 从小到大排序。定义dp[i][j]表示从 i 到 n 的人共接待 j 个人的花费(i 到 n这一段的花费)。dp[i][j]=min( dp[i+1][j] , dp[i+1][j-1] - a[i] + j*b[i] ),最后从大往小找dp[0][j]不超过K的最大的 j 即是答案。View Code #in 阅读全文
posted @ 2012-09-18 17:18 BeatLJ 阅读(295) 评论(0) 推荐(0)
摘要:题意:n个地点构成一棵树,第 i 个地点有 t_i 个人,现要选一个地点开会,求所有人行走距离之和的最小值。N<=10^5分析:先任选一个地点,求出总代价,然后就能求出相邻点的代价,一遍dfs就能求出所有点的代价。dfs会爆栈,需要开内存挂:#pragma comment(linker, "/STACK:1024000000,1024000000")View Code #include <stdio.h>#include <string.h>#include <algorithm>using namespace std;#defin 阅读全文
posted @ 2012-09-17 17:33 BeatLJ 阅读(258) 评论(0) 推荐(0)
摘要:题意:给一个无向图连通,图中每个结点都有一个权值,问能否割掉图中的一条边,使得图变为2个连通支,若能,使2个连通支中权值和的差最小,输出差的绝对值。N<=10^4分析:dfs时用tarjan判断边是否为割边,若是就更新答案。需注意的是有重边。View Code #include <stdio.h>#include <string.h>#include <algorithm>using namespace std;#define N 10000#define M 20000#define INF 0x3f3f3f3fint n,m,e,w[N];int 阅读全文
posted @ 2012-09-17 17:24 BeatLJ 阅读(225) 评论(0) 推荐(0)
摘要:题意:对树中每个结点求其与能到达的最远结点的距离。N<=10^4分析:先求出树的直径(树中距离最远的2个点之间路径),对每个结点,求到达直径2个端点的距离,较大的即为结果。View Code #include <stdio.h>#include <string.h>#include <algorithm>using namespace std;#define N 10001int n,e;int first[N],next[N<<1],v[N<<1],w[N<<1];int dx[N],dy[N];void init 阅读全文
posted @ 2012-09-17 17:19 BeatLJ 阅读(208) 评论(0) 推荐(0)
摘要:题意:求树的最大点独立集中点的数目。View Code #include <stdio.h>#include <string.h>#include <algorithm>using namespace std;#define N 6001int n,e;int w[N],first[N],next[N],v[N],p[N];int dp[N][2];void init(){ e=0; memset(first,-1,sizeof(first)); memset(p,0,sizeof(p)); memset(dp,0,sizeof(dp));}void add 阅读全文
posted @ 2012-09-17 17:13 BeatLJ 阅读(188) 评论(0) 推荐(0)
摘要:题意:给定一棵树,边权表示通过此边的代价,给k个机器人,指定从点s出发,求遍历所有结点的最小代价和。分析:设计状态时不难想到用dp[i][j]表示从结点 i 出发遍历以它为根的子树的最小代价,但是转移时就遇到麻烦了,考虑只给你 1 个机器人的时候,这时要遍历所有结点就必然要走回头路,如果我们对每个结点再增加一个信息,表示从 i 出发遍历以 i 为根的子树且最后回到 i 的最小代价,这样转移就好办了,对于每个结点,将 j 个机器人分配给它的所有子结点,若分配 0 个机器人,则表明要派一个机器人去,遍历完了又回到 i 。方便起见,就以dp[i][0]表示从 i 出发遍历完子树 i 又回到i的最小代 阅读全文
posted @ 2012-09-17 17:07 BeatLJ 阅读(183) 评论(0) 推荐(0)
摘要:题意:给一棵带权有根树,边权表示切断此边的代价,现有一台切边的机器,但它有一个上限值up limited power,只能切断边权不超过up limited power的边,现要切断根节点与所有叶子结点的联系,总代价即为所切边的边权和,给定最大代价m,求最小的up limited power。数据范围:n<=1000,m<=1000000,1<=边权wi<=1000分析:二分答案,然后树DP判断。复杂度为O(NlogW)View Code #include <stdio.h>#include <string.h>#include <algo 阅读全文
posted @ 2012-09-16 11:45 BeatLJ 阅读(205) 评论(0) 推荐(0)
摘要:题意:给n个病毒字符串和一个程序字符串,若程序字符串包含某个病毒字符串或者它的反串,则包含这个病毒,问所给程序字符串包含多少个病毒?分析:用病毒串和反串建立AC自动机,然后求包含多少病毒,但同一个病毒可能会被计算2次(如果病毒和它的反串都出现在程序中),对于每个病毒,它在自动机中都有2个结点代表自身结尾和反串结尾,我们对每个病毒都记录这2个结点,在统计的过程中可以把走过的结点打上标记,最后再统计哪些病毒的2个结点都被标记,说明被统计了2次,需要减去一次,这样就没问题了。但是题中说了程序串是压缩的,所以需要先需处理,而且还要考虑嵌套压缩的情况,当时就没考虑到……View Code #includ 阅读全文
posted @ 2012-09-14 23:17 BeatLJ 阅读(282) 评论(0) 推荐(0)
摘要:分析:只需枚举4个起始时间即可,确定起始时间后,后面的时间就都确定了,求最大值时,利用贪心策略,每次都选结束时间最早的。题中说的时间不会超过1000,貌似数据中有大于1000的,被坑了……View Code #include <stdio.h>#include <string.h>#include <algorithm>using namespace std;#define N 300struct node{ int x,y; bool operator<(const node &t) const { return y<t.y; }};i 阅读全文
posted @ 2012-09-14 23:04 BeatLJ 阅读(259) 评论(0) 推荐(0)
摘要:题意:求区间(P , Q]中第K个恰含x个4和y个7的数。P,Q<2^63分析:以前看到的数位DP的题都是求某个区间内满足给定条件的数的个数,看到这题我们一下可能没什么想法,也可能想到先求区间内的个数,然后二分答案,初看起来可以,但仔细想想就会发现有问题,因为即使知道(P , Q]内恰好有K个,你还是不知道第K个是哪个,所以二分貌似做不了。后来搜了下别人的解法,看过之后才恍然大悟,求解的过程非常巧妙,简而言之就是从高到低依次确定各个位的数字。不解释太多,看代码就明白了……View Code #include <stdio.h>#include <string.h> 阅读全文
posted @ 2012-09-14 22:57 BeatLJ 阅读(344) 评论(0) 推荐(0)
摘要:题意:维护一个整数序列,支持2种操作:1 a b k c将区间[a b]中满足(i-a)%k==0的数加上c;2 x查询第x个数的值。数据范围:整数个数N<=50000,操作次数Q<=50000,1<=k<=10分析:此题关键在于处理修改操作,我们发现修改是等间隔的,所以可以将数组拆开如下:k=1时,间隔为0:1 2 34 5 6 7 8 9 10……k=2时,间隔为1:1 3 5 7 9 ……2 4 6 8 10……k=3时,间隔为2:1 4 7 10……2 5 8 ……3 6 9 ……按以上拆法,可以得到55个整数序列,每次修改都是对其中一个序列进行的连续修改,由于 阅读全文
posted @ 2012-09-11 16:07 BeatLJ 阅读(183) 评论(0) 推荐(0)
摘要:题意:给n个正整数,代表n条边,现将n条边拼成一个三角形(每条边都要用到),问能组成多少个不同的三角形。View Code #include <stdio.h>#include <algorithm>#include <set>using namespace std;#define MP make_pairint l[15],n;int x[3];struct pro{ int ans,sum; set<pair<int,pair<int,int> > > Set; void init() { ans=sum=0; Set 阅读全文
posted @ 2012-09-11 15:45 BeatLJ 阅读(205) 评论(0) 推荐(0)
摘要:长春网赛倒数第2题题意:给一颗带权树,树的边权代表通过所需的费用,树中每个节点有一个value,代表财富值,从结点1出发,求在时间T内到达结点n最多能带走的财富。分析:从1到n有一条必经之路,对这条路上的结点用树形DP求泛型背包,然后对这些点进行分组背包。View Code #include <stdio.h>#include <string.h>#include <queue>using namespace std;#define MAX(a,b) ((a)>(b)?(a):(b))#define N 101int n,T,e;int first[N 阅读全文
posted @ 2012-09-10 17:32 BeatLJ 阅读(221) 评论(0) 推荐(0)
摘要:亚洲区长春站网络赛第2题题意:Alice和Bob各有n张卡片,如果卡片a的宽和高都不小于卡片b,则a能覆盖b,问Alice的卡片最多能覆盖多少Bob的卡片。每张卡片只能用一次,每张最多只能覆盖一张。分析:在这里卡片之间的关系有3种,1、a能覆盖b;2、b能覆盖a;3、a不能覆盖b,b不也覆盖不了a(a和b相同的情况可以并入前面2种)。我们将双方卡片排序(先比较高,然后比较宽,小的在前)后,若Alice最小的卡片不能覆盖Bob最小的卡片,则Alice这张卡片可以直接抛弃,如果能覆盖,则一定要覆盖一个宽度最大的。我们将Bob的卡片中高度比它小的存入set(关键字为最大宽度-自身宽度),要注意相同卡 阅读全文
posted @ 2012-09-10 17:25 BeatLJ 阅读(269) 评论(0) 推荐(0)
摘要:Problem Description:A peak number is defined as continuous digits {D0, D1 … Dn-1} (D0 > 0 and n >= 3), which exist Dm (0 < m < n - 1) satisfied Di-1 < Di (0 < i <= m) and Di > Di+1 (m <= i < n - 1).A number is called bi-peak if it is a concatenation of two peak numbers. 阅读全文
posted @ 2012-09-03 23:08 BeatLJ 阅读(577) 评论(0) 推荐(1)
摘要:题意:求区间[x , y]中beautiful number的个数,a positive integer number is beautiful if and only if it is divisible by each of its nonzero digits.分析:一个数能被它的所有非零数位整除,则能被它们的最小公倍数整除,而1到9的最小公倍数为2520,数位DP时我们只需保存前面那些位的最小公倍数就可进行状态转移,到边界时就把所有位的lcm求出了,为了判断这个数能否被它的所有数位整除,我们还需要这个数的值,显然要记录值是不可能的,其实我们只需记录它对2520的模即可,这样我们就可以设 阅读全文
posted @ 2012-09-02 22:33 BeatLJ 阅读(1996) 评论(0) 推荐(0)
摘要:题意:给m个字符串,求长为n且至少包含k个上述字符串的字符串有多少个。数据范围:(1<=n<=25),(0<=m<=10)分析:用dp[i][cur][s]表示走i步后,到达结点cur,包含的字符串压缩为状态s(第x位为1表示包含第x个字符串)的字符串有多少个。TLE:当dp[i-1][pre][s]=0时,直接continue,不用进入下一层循环,经此优化后就AC了。View Code #include <stdio.h>#include <string.h>#include <queue>using namespace std;# 阅读全文
posted @ 2012-09-02 17:45 BeatLJ 阅读(321) 评论(0) 推荐(0)
摘要:题意:给n个01字符串,求区间[x , y]中有多少个数写成BCD码后不包含以上01串。分析:先用01字符串建立AC自动机(注意标记危险结点),然后DP。dp[i][s]表示扫描前i位后有多少个数会到达自动机的结点s.TLE:数位DP写搓了……(为此今天专门学习了下数位DP的dfs写法,发现确实比递推的快不少)WA:1、高精度减1写错了; 2、由于有取模,所以cal(y)可能小于cal(x-1),输出的时候没考虑到。View Code #include <stdio.h>#include <string.h>#include <queue>using nam 阅读全文
posted @ 2012-09-02 16:43 BeatLJ 阅读(380) 评论(0) 推荐(0)
摘要:题意:求[x , y]中有多少个平衡数。平衡数:选定一位作为支点,若左右的力矩平衡则该数是平衡数,否则不是。For example, 4139 is a balanced number with pivot fixed at 3. The torqueses are 4*2 + 1*1 = 9 and 9*1 = 9View Code #include <stdio.h>#include <string.h>#define N 19#define M 1378typedef __int64 LL;LL dp[N][N][M];int digit[N];LL dfs(in 阅读全文
posted @ 2012-09-02 16:26 BeatLJ 阅读(429) 评论(0) 推荐(0)
摘要:题意:求1-n中有多少个数含字符串”13"且能被13整除。(1 <= n <= 1000000000).练习数位DP的dfs写法。View Code #include <stdio.h>#include <string.h>#define N 10int dp[N][13][3],digit[N];int dfs(int pos,int r,int s,int f){ if(pos==-1) return r==0&&s==2; if(!f&&dp[pos][r][s]!=-1) return dp[pos][r][ 阅读全文
posted @ 2012-09-02 16:21 BeatLJ 阅读(209) 评论(0) 推荐(0)
摘要:题意:求1-N中有多少个数包含字符串"49"。1 <= N <= 2^63-1重写这题就是为了学习数位DP的dfs写法,感觉dfs的写法思路更清晰,速度也更快。View Code #include <stdio.h>#include <string.h>#define N 20typedef __int64 LL;LL dp[N][3];int digit[N];LL dfs(int pos,int s,int f){ if(pos==-1) return s==2; if(!f&&dp[pos][s]!=-1) retu 阅读全文
posted @ 2012-09-02 16:18 BeatLJ 阅读(230) 评论(0) 推荐(0)

点击右上角即可分享
微信分享提示