
挑战程序设计竞赛
羁绊残阳
四川大学计算机科学与技术
展开
-
poj 3253 哈夫曼树
背景:开始自己想了一个贪心思路,结果是错的!!原创 2015-04-10 17:08:07 · 610 阅读 · 0 评论 -
poj 2758 多重部分和
题意:给你一个n行4列的矩阵,从每列选择一个数字,问这四个数字加起来为0的数字组合有多少个?思路:暴力O(n4)O(n^4)超时,只有把前两个数字的所有和枚举出来(O(n2)O(n^2)),然后排序(O(nlogn)O(nlog^n)),最后枚举最后两数的所有组合,每一个组合用二分查找已经排序好的前两个数字组合(O(n2logn)O(n^2log^n)),故总的复杂度是:O(n2logn)O(n^原创 2015-05-29 11:33:34 · 1192 阅读 · 1 评论 -
poj3169 差分约束系统
题意:从1到n,n个数,从左向右一次排列。给定两种形式的约束条件: 1.xix_i与yiy_i的最大距离为dkd_k 2.xix_i与yiy_i的最小距离为dkd_k 问满足这些限定条件的情况下,数1和n的最大距离是多少?(若约束条件相互矛盾则输出-1,若最大距离可以为无穷大则输出-2)知识补充:差分约束系统的概念:由n个变量和m个约束条件(实数)组成,且都是形如:xi−yj≤bk(x,y为原创 2015-07-25 18:07:34 · 884 阅读 · 5 评论 -
《挑战程序设计竞赛》 扩展欧几里得算法 + SPFA
知识补充:SPFA算法:Bellman-Ford算法的优化算法,方法是: 1.把当前点(最开始是起点)入队,并将标记是否在队列中的visit数组的当前点设为true。原创 2015-07-28 13:59:09 · 758 阅读 · 0 评论 -
UVa 10006 快速幂运算
知识补充: 如果a和b关于m同于,那么(a - b )是m的整数倍。负数取余运算:不同的语言有不同的方法,其中C和JAVA是按第一个数的符号确定结果的符号,C++则要依据系统而定。 取余运算的发展:1.(a+b)%p=(a%p+b%p)%p1.(a + b) \% p = (a \% p + b \% p) \% p2.(a∗b)%p=(a%p∗b%p)%p2.(a * b) \% p原创 2015-07-31 16:53:16 · 592 阅读 · 0 评论 -
GCJ 2008 Round 1A A 排序贪心
题意:给你两个维数相同的向量,它们之中的元素可以任意交换位置,求它们内积的最大值。思路:乍一看此题摸不着什么头脑,只是凭借直觉感觉一个升序一个降序求内积即可。这样的感觉有时是对的,有时是错的,如果实现复杂的话比赛中就不该冒这个险。最好简单的证明一下。 证明:先讨论二维向量的情况对于按升序排列的(x1,x2)(x1, x2)按升序排列的(y1,y2)(y1, y2),显然恰与思路想法相反,其内积减去原创 2015-08-01 09:33:11 · 754 阅读 · 0 评论 -
poj 3255 最短路和次短路
题意:求从起点到终点的次短路Bellman-Ford算法:把有向图的边存起来,然后每次扫描所有边,来更新起点到每个点的最短路,当这一次扫描,一次更新都没有的时候,说明所有顶点的最短路已经求得。复杂度是O(|E|∗|V|)O(|E|*|V|)。根据这个思想还可以来判断图中存不存在负圈。Dijkstra算法(戴克斯特拉):1.初始所有顶点都是未使用过,且除了起点最短距离为0外,所有顶点最短距离原创 2015-07-21 11:45:32 · 787 阅读 · 0 评论 -
poj 1979 dfs
水过,注意边界不能超出。#include <iostream>using namespace std;int n, m, sx, sy, dir[4][2] = {0, -1, 0, 1, 1, 0, -1, 0}, count;char diagram[23][23];void get_diagram(void) { for (int i = 0; i < n; i++) {原创 2015-07-22 21:56:10 · 641 阅读 · 0 评论 -
poj 2139 Floyd-Warshall算法求最短路
题意:不想说,这个题意思了,含糊不清=-= Dijkstra算法,无法计算有负边的图,原因是有负边的图存在是会打乱Dijkstra算法的前提,当前优先队列取出点的距离为起点到该点的最小距离,因为如果后面有负边这个距离会更小。除此之外Bellman-Ford算法和Floyd-warshall算法都可以计算有负边的图,且判断是否有负圈。Floyd-Warshall算法:该算法用到了动态规划归约的思想原创 2015-07-22 11:16:29 · 701 阅读 · 0 评论 -
poj 3723 Kruskal最小生成树
题意:一堆男女加进一个组,每人的加入费用是10000元。男女之间存在一种亲密度,在加入一个人的时候,ta的加入费是10000减去已经入组的异性中和亲密度最大的。问以某种顺序入组,的最小总费用是多少?思路:主要是把这些亲密关系看做无向图,然后要以最小的代价包含所有人,显然是最小生成树。我的做法是,先把有亲密关系的那些人建立无向图,然后求出最小生成树。剩下的人入组费统一10000元。知识补充:原创 2015-07-24 11:49:58 · 774 阅读 · 0 评论 -
挑战程序设计竞赛 二叉堆(优先队列)的实现
几个概念:完全二叉树:是指除叶子节点那层外,叶子节点以上的第k层都含有2k2^k个节点而且叶子节那层的节点都靠左方。满二叉树:与完全二叉树先比,多了连叶子节点也要全满的限制条件。堆的代码实现(数组实现):int heap[10000], sz = 0;void push(int x) { //向堆里面增加元素X int i = sz++, p; while(i > 0)原创 2015-04-17 18:26:17 · 754 阅读 · 0 评论 -
挑战程序设计竞赛 划分数,贝尔数,斯特灵数
斯特灵数:把nn个数划分为恰好kk个非空集合的个数,记为S(n,k)S(n, k)。且有:S(n,1)=S(n,n)=1S(n, 1) = S(n, n) = 1。 有递推关系式:S(n+1,k)=S(n,k−1)+kS(n,k−1)S(n + 1, k) = S(n, k - 1) + kS(n, k - 1) 贝儿数:把nn个数划分为非空集合的所有划分数。有:Bn=∑i=0nS(n,i)Bn原创 2015-04-17 11:01:04 · 874 阅读 · 0 评论 -
poj 3253 哈夫曼树
背景:开始自己想了一个贪心思路,结果是错的。其实这个题是哈夫曼树的思想,贪心只是哈夫曼树的证明和构造思想。 哈夫曼树:一种带权最短二叉树(也就是所有叶子节点的权重乘以深度的和最小),在实际中是用来做最高效信息编码的。信息的频率就是权重,一个频率很低的数,它的编码就应该长,树的深度就应该大。实际信息编码会根据信息字符的频率来构建一个哈夫曼树,已达到最高效。本题和哈夫曼树是一个很好的契合,解决本题原创 2015-04-26 09:03:35 · 949 阅读 · 0 评论 -
poj 3617 贪心
背景:第一次没有考虑到相等的情况,wa了,改正后re了几次。。。思路:贪心思想,但是当两边都相等的时候选哪一边才是关键,这是我的处理方法是,继续对2和n-1个字符比较,如果2小就从左边开始,n-1小就从右边开始,如果还是相等就继续比较2和n-2........书上的思想也是类似原理。我的代码:#include#include#includeusing namespace std;原创 2015-04-10 11:23:17 · 622 阅读 · 0 评论 -
poj 3069 贪心
背景:1Y,但是思考的时候并没有充分思考好思路再写,而是有点含糊的边写边想,这样不好,一定要思路已经十分明确了再写。思路:从一个没有被覆盖的点开始,在以它为中心半径为r的区域内,至少有一个点标记,那么就选择,距离它最远的点。标记这个点之后,算出下一个没有被标记的点,重复以上操作即可。这里把最后一个数据的后一个数调为INF是解决之后一个数的良好方法。贪心策略往往是十分高效的方法,这需要十分良原创 2015-04-10 15:44:04 · 634 阅读 · 0 评论 -
hdu 1159 经典dp最长公共子序列
背景:上次比赛就没有做出来,回来根据实际意义半天也想不出如何dp,结果从猜转移方程入手,竟然想对了!开始想把空间优化到一维数组,没有想到要用同维度左边的值wa了。思路:dp[i][j]=max{max[i-1][j],max[i][j-1],max[i-1][j-1]+(a[i] == b[j])}//dp[i][j]定以为,a串的前i个字符和b串的前b个字符的最大字串和,为选a串的第i原创 2015-04-10 22:37:00 · 574 阅读 · 0 评论 -
poj 2431 优先队列&贪心
几个概念:完全二叉树:是指除叶子节点那层外,叶子节点以上的第k层都含有2k2^k个节点而且叶子节那层的节点都靠左方。满二叉树:与完全二叉树先比,多了连叶子节点也要全满的限制条件。堆的代码实现(数组实现):int heap[10000], sz = 0;void push(int x) { //向堆里面增加元素X int i = sz++, p; while(i > 0)原创 2015-04-18 17:38:12 · 556 阅读 · 0 评论 -
挑战程序设计竞赛 01背包变换对象
01背包式最简单的背包问题,书上是由深度优先搜索的记忆化搜索的递归实现到处递推的解决方法就是01背包,把所有i和j的情况都记下来,总共不过n*v种情况。 而01背包之2是简单01背包变换对象之后的做法。 题目描述如下: 有n个价值和花费分别为weight[i]和cost[i]的物品,把这些物品装进容量为V的背包中,求最大价值? 但是现在条件是:V<=109,weight[i]<100,n<1原创 2015-04-11 13:50:37 · 996 阅读 · 0 评论 -
挑战程序设计竞赛 多重部分和问题(恰好装满的完全背包)
这里一般的完全背包做法:转化为01背包(可以对01背包进行二进制优化),复杂度是O(n∗V∗logV/cost[i]2)O(n*V*log^{V/cost[i]}_2)。 这里巧妙的定义了一种方法让复杂度降到了O(n∗V)O(n*V) **转移方程思想:定义能装满dp[i][j]为容量为j时,第i种物品的剩余个数,则: if (dp[i-1][j] >= 0),dp[i][j]=m原创 2015-04-11 15:12:17 · 1114 阅读 · 2 评论 -
poj 2533 最长上升子序列
背景:最长上升字串,自己想了好久,想出了O(n2)O(n^2)的方法,书上写有O(nlogn)O(nlogn)的方法。#include #include #include #include using namespace std;const int M = 1009, INF = 0x3fffffff;int main(void) { int n, str[1009],原创 2015-04-14 17:24:10 · 448 阅读 · 0 评论 -
poj 1852思维题
背景:挑战程序设计竞赛上的题,好思维。来就想暴力枚举都还没有仔细思考有没有数学规律,n超过20就不适合用2的n次方的算法了。思路:最短时间十分容易讨论,这里最大时间很巧妙,两只蚂蚁相撞然后各自反向走,可以想成两只蚂蚁绕过,各走各的,这样早最大时间就简单了,就是所有走到端点的时间中最大的。代码:#include #include #include #include #include原创 2015-04-09 18:11:59 · 624 阅读 · 0 评论 -
《挑战程序设计竞赛》 2^n类型的深搜
题意:从n个数中选取任意个数的数,看是否等于k。代码给出了十分清晰简洁的优雅递归写法。#include #include #include #include #include #include #include #include #include #include using namespace std;typedef long long int LL;const in原创 2015-04-09 22:14:56 · 651 阅读 · 0 评论 -
SCU2016-01 G题(最大流 + floyd_warshall)
分析:其实就是经典的限制终点的容量的最大流。建立超级源点和汇点。最小化最大路径,二分一下。对于任意最短路Floyd_warshall一下。 code:#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <vector>#include <queue>using namesp原创 2016-08-26 19:25:24 · 535 阅读 · 0 评论