08 2012 档案
摘要:题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=3999本题为简单二叉排序树,先按排序树创建树,然后先序遍历二叉树,输出的时候最后一个数字后面没有空格。数组实现:#include#include#define N 100005int tree[N],left[N],right[N],a[N],num,flg;//tree数组用来保存树节点的值,left,right数组用来保存结点的左右子树,void insert(int index,int x){ if( x #includestruct node{ int data; struct node *
阅读全文
摘要:题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1421状态Dp[i][j]为前i件物品选j对的最优解当i=j*2时,只有一种选择即 Dp[i-2][j-1]+(w[i]-w[i-1])^2当i>j*2时,Dp[i][j] = min(Dp[i-1][j],Dp[i-2][j-1]+(w[j]-w[j-1])^2)#include#includeusing namespace std;#define min(x,y) (x)= j*2)//当i-1>= j*2的时候 dp[i][j] = min(dp[i-1][j],dp[i-2][j
阅读全文
摘要:题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=3732题目大意:阿辉要记单词,所有单词的长度都不超过10个字符,每个单词都有一定的价值跟复杂性,知道每个单词的价值跟复杂性都写下来了,阿辉写单词的总的复杂度不能超过C,要你求阿辉可以得到的最大价值。解题思路:乍一看本题为一个简单0 1背包问题,但用0 1 背包做的时间复杂度为10^9在一秒中内不可能完成,但细看题目后发现Vi和Ci都小于等于10也就是说价值和费用的种类总共只有一百种,只需要统计所有价值、费用相同的数目及可以将问题转化为一个多重背包问题。源码及注释:#include#includein
阅读全文
摘要:最近发现自己在高级数据结构方面好薄弱的,于是看了很多文档,发现这篇不错。数据结构——堆的操作和实现当应用优先级队列或者进行堆排序时,一般利用堆来实现。堆是一个完全(除最底层外都是满的)二叉树,并满足如下条件:1、根结点若有子树,则子树一定也是堆。2、根结点一定大于(或小于)子结点。因为要求堆必须是完全二叉树,所以可以用线性的数据结构,比如数组,来实现堆。利用数组实现,则对于长为N的堆中的元素从0到N-1排列,有:i的父结点:Parent(i)=(i+1)/2-1i的左叶子:Left(i)=(i+1)*2-1i的右叶子:Right(i)=(i+1)*2堆的操作主要以一个“堆化”(Heapify)
阅读全文
摘要:题目地址:http://poj.org/problem?id=2392题目大意:有一头奶牛要上太空,他有很多种石头,每种石头的高度是hi,但是不能放到ai之上的高度,并且这种石头有ci个将这些石头叠加起来,问能够达到的最高高度。解题思路:先将石头可以放置的最大高度按从小到大的顺序进行排序,因为只有先放置最大高度最低的才能得到最优解,也就是说让一种石头尽可能高的放。最大值必须初始化为0,因为存在高度为0的情况。#include#include#includeusing namespace std;int dp[400005];struct node{ int h,a,c; bool operat
阅读全文
摘要:题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=2639第K优解问题其基本思想是将每个状态都表示成有序队列,将状态转移方程中的max/min转化成有序队列的合并。这里仍然以01背包为例讲解一下。首先看01背包求最优解的状态转移方程:f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}。如果要求第K优解,那么状态f[i][v]就应该是一个大小为K的数组f[i][v][1..K]。其中f[i][v][k]表示前i个物品、背包大小为v时,第k优解的值。 “f[i][v]是一个大小为K的数组”这一句,熟悉C语言的同学可能比较
阅读全文
摘要:题目:http://acm.hdu.edu.cn/showproblem.php?pid=2955题目大意:有一个小偷要偷银行的钱,可是他偷没家银行总是有一定的概率被抓,现在给了你一个概率P,只要他被抓的概率乘积不大与P,他就是安全的。问你在他安全的情况下,他最多可以偷多少钱。容量为银行钱的总和,价值就是偷到的钱,花费就是被抓的概率。dp方程:dp[j] = Max(dp[j],dp[j-w[i]]*(1-p[i])) #include#include#includeint w[101];float dp[10005];int main(){ int t,n,i,j,sum; float p,
阅读全文
摘要:题目:http://acm.hdu.edu.cn/showproblem.php?pid=2159二维费用的背包问题是指:对于每件物品,具有两种不同的费用;选择这件物品必须同时付出这两种代价;对于每种代价都有一个可付出的最大值(背包容量)。问怎样选择物品可以得到最大的价值。设这两种代价分别为代价1和代价2,第i件物品所需的两种代价分别为a[i]和b[i]。两种代价可付出的最大值(两种背包容量)分别为V和U。物品的价值为w[i]。简单二维费用背包问题,解题源代码及注释如下:#include#includeint a[100],b[100],dp[1001][1001];int main(){ i
阅读全文
摘要:题目:http://acm.hdu.edu.cn/showproblem.php?pid=2844本题为简单多重背包,解题源码及注释如下:#include#includeint w[101],c[101],dp[100100];int max(int a,int b){ return a > b ? a : b;}int main(){ int n,m,num; int i,j,k; while(scanf("%d%d",&n,&m) != EOF && (m||n)) { for(i = 0; i m)//完全背包 { for(j =
阅读全文
摘要:题目:http://acm.hdu.edu.cn/showproblem.php?pid=1171本题为一个简单的多重背包问题。解题源码及注释:#include#includeint max(int a,int b){ return a > b ? a : b;}int main(){ int N,sum,V,i,j,k; int w[51],n[51];//w[i]用来保存第i件物品的价值,此题中费用与同一物品的价值相等,n[i]用来保存第i件物品的数量 int dp[250000];//总价值最大为250000 while(scanf("%d",&N) ,
阅读全文
摘要:题目:http://acm.hdu.edu.cn/showproblem.php?pid=1162#include#includebool P[110];//标记数组,标记某一个点是否已经连接到树上struct point{ double x,y;}Point[110],A[110];double SegLen(point a,point b){ return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));}int main(){ int n,i,num,j; int Min; //Min表示第Min个点到已经连接...
阅读全文
摘要:题目:http://acm.hdu.edu.cn/showproblem.php?pid=3371解题思路:题目要我们在已经有的一部分点相连的情况下求最小生成树。首先用并查集将所有城市分离成一个独立的点然后用已经存在的路去连接一部分点,使其构成一棵树,然后用Kruskal 算法 贪心求出最小生成树。实现代码如下:#include #include struct road { int x,y; int w; }a[25010]; int per[510]; int cmp(const void *a,const void *b) { if(((ro...
阅读全文
摘要:题目:http://acm.hdu.edu.cn/showproblem.php?pid=1863最小生成树kruskal算法:http://www.zhuoda.org/irini/78592.html一开始看到题目的时候就知道是求最小生成树的题目,而且可以用并查集了构建树,但是不知道怎么将并查集和求最小生成树的算法结合起来,后来看到了最小生成树Kruskal算法是用贪心求最小生成树的,每次都都取权值最小的边去构建树,如果两点的祖先结点相同,及直接连通或者间接连通的时候则不再建边否则创建边使连点直接或间接连通。实现算法如下:#include#include#include#define MA
阅读全文
摘要:题目:http://acm.hdu.edu.cn/showproblem.php?pid=1166基维百科:http://zh.wikipedia.org/wiki/%E6%A0%91%E7%8A%B6%E6%95%B0%E7%BB%84http://duanple.blog.163.com/blog/static/7097176720081131113145832/树状数组源码及部分注释:#include#include#define MAX 50010int N;int per[MAX],C[MAX];int lowbit(int n){//此函数实际就是将n的二进制表示形式留下最右边的1
阅读全文
摘要:Cash MachineTime Limit: 1000MSMemory Limit: 10000KTotal Submissions: 19960Accepted: 6954DescriptionA Bank plans to install a machine for cash withdrawal. The machine is able to deliver appropriate @ bills for a requested cash amount. The machine uses exactly N distinct bill denominations, say Dk, k=
阅读全文
摘要:一、基本描述类似于回溯法,也是一种在问题的解空间树T上搜索问题解的算法。但在一般情况下,分支限界法与回溯法的求解目标不同。回溯法的求解目标是找出T中满足约束条件的所有解,而分支限界法的求解目标则是找出满足约束条件的一个解,或是在满足约束条件的解中找出使某一目标函数值达到极大或极小的解,即在某种意义下的最优解。(1)分支搜索算法所谓“分支”就是采用广度优先的策略,依次搜索E-结点的所有分支,也就是所有相邻结点,抛弃不满足约束条件的结点,其余结点加入活结点表。然后从表中选择一个结点作为下一个E-结点,继续搜索。选择下一个E-结点的方式不同,则会有几种不同的分支搜索方式。1)FIFO搜索2)LIFO
阅读全文
摘要:1、概念回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径。回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。许多复杂的,规模较大的问题都可以使用回溯法,有“通用解题方法”的美称。2、基本思想在包含问题的所有解的解空间树中,按照深度优先搜索的策略,从根结点出发深度探索解空间树。当探索到某一结点时,要先判断该结点是否包含问题的解,如果包含,就从该结点出发继续探
阅读全文
摘要:贪心算法一、基本概念: 所谓贪心算法是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。 贪心算法没有固定的算法框架,算法设计的关键是贪心策略的选择。必须注意的是,贪心算法不是对所有问题都能得到整体最优解,选择的贪心策略必须具备无后效性,即某个状态以后的过程不会影响以前的状态,只与当前状态有关。 所以对所采用的贪心策略一定要仔细分析其是否满足无后效性。二、贪心算法的基本思路: 1.建立数学模型来描述问题。 2.把求解的问题分成若干个子问题。 3.对每一子问题求解,得到子问题的局部最优解。 4.把子问题的解局部最优...
阅读全文
摘要:一、基本概念 动态规划过程是:每次决策依赖于当前状态,又随即引起状态的转移。一个决策序列就是在变化的状态中产生出来的,所以,这种多阶段最优化决策解决问题的过程就称为动态规划。二、基本思想与策略 基本思想与分治法类似,也是将待求解的问题分解为若干个子问题(阶段),按顺序求解子阶段,前一子问题的解,为后一子问题的求解提供了有用的信息。在求解任一子问题时,列出各种可能的局部解,通过决策保留那些有可能达到最优的局部解,丢弃其他局部解。依次解决各子问题,最后一个子问题就是初始问题的解。 由于动态规划解决的问题多数有重叠子问题这个特点,为减少重复计算,对每一个子问题只解一次,将其不同阶段的不同状态保存在一
阅读全文
摘要:分治算法一、基本概念 在计算机科学中,分治法是一种很重要的算法。字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。这个技巧是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)…… 任何一个可以用计算机求解的问题所需的计算时间都与其规模有关。问题的规模越小,越容易直接求解,解题所需的计算时间也越少。例如,对于n个元素的排序问题,当n=1时,不需任何计算。n=2时,只要作一次比较即可排好序。n=3时只要作3次比较即可,…。而当n较大时,问题
阅读全文
摘要:__int64 mod(__int64 a, __int64 b, __int64 n){ __int64 arr[500],z = -1,y; for( ; b != 1 ; b >>= 1)//分解b为二进制,记录下分解成的位数z构造栈arr { z++; if( b % 2 == 0) arr[z] = 0; else arr[z] = 1; } //a %= n如果一开始数很大,先模一次,防止过大,求逆 y = a * a % n;//第一次去模 for(; z > 0; z--) { if(arr[z]) y = (y*a%n) * (y*a%n); else...
阅读全文
摘要:好久没写过算法了,添一个吧,写一个线段树的入门知识,比较大众化。上次在湖大,其中的一道题数据很强,我试了好多种优化都TLE,相信只能用线段树才能过。回来之后暗暗又学了一次线段树,想想好像是第三次学了,像网络流一样每学一次都有新的体会。把问题简化一下:在自然数,且所有的数不大于30000的范围内讨论一个问题:现在已知n条线段,把端点依次输入告诉你,然后有m个询问,每个询问输入一个点,要求这个点在多少条线段上出现过;最基本的解法当然就是读一个点,就把所有线段比一下,看看在不在线段中;每次询问都要把n条线段查一次,那么m次询问,就要运算m*n次,复杂度就是O(m*n)这道题m和n都是30000,那么
阅读全文
摘要:说明:二分搜尋法每次搜尋時,都會將搜尋區間分為一半,所以其搜尋時間為O(log(2)n),log(2)表示以2為底的log值,這邊要介紹的費氏搜尋,其利用費氏數列作為間隔來搜尋下一個數,所以區間收斂的速度更快,搜尋時間為O(logn)。解法:費氏搜尋使用費氏數列來決定下一個數的搜尋位置,所以必須先製作費氏數列,這在之前有提過;費氏搜尋會先透過公式計算求出第一個要搜尋數的位置,以及其代表的費氏數,以搜尋對象10個數字來說,第一個費氏數經計算後一定是F5,而第一個要搜尋的位置有兩個可能,例如若在下面的數列搜尋的話(為了計算方便,通常會將索引0訂作無限小的數,而數列由索引1開始):-∞ 1 3 5
阅读全文
摘要:【摘要】搜索和动态规划是信息学中的两大重要算法。它们各有自己的优点和缺点。针对它们的优缺点,一个新的算法——“记忆化搜索”产生了。它采用了搜索的形式与动态规划的思想,扬长避短,在解决某些题目时,有非常出色的表现。它在信息学竞赛中也有举足轻重的地位,NOI2001的cannon与NOI2002的dragon都使用到了这个算法。这篇论文着重分析了搜索、动态规划和记忆化搜索之间的联系和区别,以及各自的优缺点,并通过几个例子使得大家对记忆化搜索有一个初步的了解。【关键字】重叠子问题 拓扑关系 形式+思想【目录】一、 搜索1.搜索树2.例子——words3.效率低下的原因——重叠子问题二、 动态规划..
阅读全文
摘要:SticksTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 3171 Accepted Submission(s): 780Problem DescriptionGeorge took sticks of the same length and cut them randomly until all parts became at most 50 units long. Now he wants to return sticks to the
阅读全文
摘要:搜索是ACM竞赛中的常见算法,本文的主要内容就是分析它的 特点,以及在实际问题中如何合理的选择搜索方法,提高效率。文章的第一部分首先分析了各种基本的搜索及其各自的特点。第二部分在基本搜索方法的基础上提出 一些更高级的搜索,提高搜索的效率。第三部分将搜索和动态规划结合,高效地解决实际问题,体现搜索的广泛应用性。第四部分总结全文。 文章在分析各种搜索的同时,分析了我们在解题中应该怎样合理利用它,理论结合实际,对我们的解题实践有一定的指导意义。【 Abstract 】 Search is a algorithm which is often seen in ACM/ICPC .The main id
阅读全文

浙公网安备 33010602011771号