挑战程序设计竞赛---读书笔记
文章平均质量分 71
xiaozhuaixifu
这个作者很懒,什么都没留下…
展开
-
整数划分问题---动态规划、递归
第一:将一个整数 n 划分为 不超过m 组 的划分数 如 n=4m=3输出:4 { 1+1+2=1+3=2+2=4}思路:使用动态规划: 定义状态: dp[i][j] j的i划分的组数递推:dp[i][j]=dp[i][j-i]+dp[i-1][j] ------当m=n时,变成了常见的整数划分问题#include#includeusing namespace原创 2013-08-06 20:18:02 · 5250 阅读 · 0 评论 -
poj 2385 Apple Catching DP
题目链接:http://poj.org/problem?id=2385状态定义: dp[i][j] :=前i秒,移动j次接到的最大苹果数量。状态转移: dp[i][j]=dp[i-1][j]+num[0][i]; (j==0) dp[i][j]=max{dp[i-1][j-1],dp[i-1][j]}+num[j%2==1][i]; (1=这里输原创 2013-09-01 10:21:46 · 2072 阅读 · 1 评论 -
poj 3616 Milking Time ---DP(带权重的区间动态规划)
题目:http://poj.org/problem?id=3616这题就是一个小小变形的带权重的任务调度问题 --interval scheduling--思路:首先按照每个区间的结束时间排序,再进行预处理:算出与每个区间相互兼容的最大区间下标保存在P数组里。状态:dp[i]=max{ dp[i-1],dp[p[i]]+w[i] } 代码:1A#include#include原创 2013-09-01 11:13:17 · 2522 阅读 · 0 评论 -
poj 3280 Cheapest Palindrome ---(DP 回文串)
题目链接:http://poj.org/problem?id=3280思路: dp[i][j] :=第i个字符到第j个字符之间形成回文串的最小费用。dp[i][j]=min(dp[i+1][j]+cost[s[i-1]-'a'],dp[i][j-1]+cost[s[j-1]-'a']);if(s[i-1]==s[j-1]) dp[i][j]=min(dp[i+1][j-1],dp[i]原创 2013-09-01 17:12:57 · 1106 阅读 · 0 评论 -
poj 3258 River Hopscotch (二分搜索---最大化最小值)
题:http://poj.org/problem?id=3258思路:函数 can(int x)判断 当前的距离x能不能得到。用贪心的策略来选取N-M个点来看是否满足。注意边界条件和边界数据:#include#include#include#includeusing namespace std;const int MAXN=50005;int L,N,M,d[MAXN]原创 2013-09-14 16:40:53 · 1283 阅读 · 0 评论 -
poj 3273 Monthly Expense (二分搜索,最小化最大值)
题目:http://poj.org/problem?id=3273思路:通过定义一个函数bool can(int mid):=划分后最大段和小于等于mid(即划分后所有段和都小于等于mid)这样我们转化为求 满足该函数的 最小mid。即最小化最大值,可以通过二分搜索来做,要注意二分的边界。WR了好几次。代码:#include#include#include#include原创 2013-09-15 13:07:22 · 1250 阅读 · 0 评论 -
poj 3104 Drying (二分搜索答案)
题目:http://poj.org/problem?id=3104思路:二分一个答案,然后判断可行性,注意这题整形用long long , 另外算中值的时候: mid = lhs+ (rhs-lhs)>>1 这种会超时,如果改成 mid= (lhs+rhs)>>1就不超时了,想不通,按理说第一种会避免中间值溢出,同样是位操作,怎么第一种会超时呢?有大神路过,求指教:代码:原创 2013-09-15 21:59:10 · 1464 阅读 · 1 评论 -
K Best poj 3111 (01分数规划---二分搜索)
题目:http://poj.org/problem?id=3111思路:给定n个二元组(v,w)保留k个,使得 sigma(v)/sigma(w)的值最大:代码:#include#include#include#include#includeusing namespace std;const int Maxn=100001;const double eps=1e-8;原创 2013-09-16 21:59:38 · 1777 阅读 · 0 评论 -
POJ Sudoku 数独填数(深搜)
题目:http://poj.org/problem?id=2676思路:见代码:#include #include #include #include using namespace std;int sudoku[9][9];bool square[9][10]; // 标记每个小方格出现的数字 bool checkrow[9][10]; //标记没行出现的数字 bo原创 2013-10-03 14:01:47 · 4453 阅读 · 1 评论 -
poj 1990 MooFest (树状数组)
题目:http://poj.org/problem?id=1990思路见代码:#include#include#include#includeusing namespace std;const int MAX_N=20000+5;typedef long long ll;/*cnt:= 坐标小于 x的点的个数(cnt[x]) cntsum:= 坐标小于x的坐标点总原创 2013-09-19 13:24:22 · 955 阅读 · 0 评论 -
【挑战程序设计竞赛】分治法求一个数列逆序对的对数
此题来源于冒泡排序需要交换的次数,在冒泡排序中,我们需要交换两个元素的位置的情况是:对于位置(ia[j],我们称这是一对逆序数,我们就要求一个数列中满足这样条件的对数,当然采用暴力法两重的for循环当然可以做到,复杂度是O(n^2),我们采用分治法,类似于合并排序的思想:#include #include using namespace std;typedef long lo原创 2013-10-04 16:03:06 · 1279 阅读 · 0 评论 -
poj 3254 Corn Fields (状态压缩DP)
题目:http://poj.org/problem?id=3254思路见代码:#includeusing namespace std;const int MOD=100000000;const int MAX_N_M=12;int row_state[MAX_N_M];// 枚举出合法的状态数 int LegalState[2000],nstate;int dp[MAX原创 2013-09-20 21:54:41 · 1231 阅读 · 0 评论 -
【九度0J】 题目1535:重叠的最长子串 (扩展KMP算法)(滚动哈希算法--Rabin-Karp算法)
题目描述:给定两个字符串,求它们前后重叠的最长子串的长度,比如"abcde"和“cdefg”是"cde",长度为3。输入:输入可能包含多个测试案例。对于每个测试案例只有一行, 包含两个字符串。字符串长度不超过1000000,仅包含字符'a'-'z'。输出:对应每个测试案例,输出它们前后重叠的最长子串的长度。样例原创 2013-10-06 15:52:55 · 3411 阅读 · 0 评论 -
利用矩阵快速幂求斐波那契数列
我们知道如果用记忆化搜索逐项递推可以将复杂度降低到O(n),但是对于更大规模的输入,这个算法效率还是不够高,那么我们考虑更高效的算法:二阶递推:f(n+2)=(1 1) f(n+1) f(n+1) (1 0) f(n)上面等式两边分别是矩阵,那么矩阵A就是等式右边第一个式子。只要求出A的n次,就可以求出f(n)。我们使用快速幂来求,这个算法的复原创 2013-08-25 15:41:42 · 2067 阅读 · 0 评论 -
最大化平均值---二分搜索
有n个物品的重量和价值分别是w[i]和v[i],从中选出K个物品使得单位重量的价值最大。11一般想到的是按单位价值对物品排序,然后贪心选取,但是这个方法是错误的,对于有样例不满足。我们一般用二分搜索来做(其实这就是一个01分数规划)我们定义:条件 C(x) :=可以选k个物品使得单位重量的价值不小于x。因此原问题转换成了求解满足条件C(x)的最大x。那么怎么判断C(x)是否原创 2013-08-12 13:23:58 · 955 阅读 · 0 评论 -
poj 2411 Mondriaan's Dream 状态压缩DP
http://blog.csdn.net/hopeztm/article/details/8062562这篇博文比较容易懂。题目这个题目的题意很容易理解,在一个N*M的格子里,我们现在有两种类型的 砖块,1 * 2 和 2 * 1,问一共有多少种方案,可以将整个N*M的空间都填满。最简单的例子就是下面的了:编程之美中题目:某年夏天,位于希转载 2013-08-23 14:15:29 · 2234 阅读 · 0 评论 -
hdu hdoj 1166 敌兵布阵 树状数组
Problem DescriptionC国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了。A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就是要监视这些工兵营地的活动情况。由于采取了某种先进的监测手段,所以每个工兵营地的人数C国都掌握的一清二楚,每个工兵营地的人数都有可能发生变动,可能增加或减少若干人手,但这些都逃不过C国的监视原创 2013-08-18 22:11:06 · 927 阅读 · 0 评论 -
POJ 2104 K-th Number 线段树
给定一个数列 a1,a2,a3......an和m个三元组表示查询,对于每个查询(i,j,k)输出 ai.....aj的升序排列中的第k个数。我们把数列用线段树维护起来,线段树的每个节点维护了对应区间排好序的结果,计算在某个区间不超过x的数的个数,只要递归进行操作即可。求出在某个区间里不超过x的数的个数之后,通过对x进行二分搜索来求出第k个数。#include #include #原创 2013-08-20 21:19:21 · 1141 阅读 · 0 评论 -
Bellman-Ford 算法 单源最短路径问题
当给定的图是一个DAG,且存在 负边的时候,Dijkstra算法是不能用的,这时,只要图中不存在负圈,我们采用此算法能得出源点到每一个点的最短距离:#include#include#includeusing namespace std;const int INF=999999;const int maxn=100+10;struct edge{ int from,to,cost;原创 2013-08-07 22:51:16 · 1274 阅读 · 0 评论 -
hdu/hdoj 1232 畅通工程---并查集
畅通工程Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 22833 Accepted Submission(s): 11896Problem Description某省调查城镇交通状况,得到现有城镇道路原创 2013-08-07 20:26:49 · 1364 阅读 · 0 评论 -
任意两点间的最短路径---floyd_warshall算法
使用DP的思想:考虑从i到j的最短路径经过K一次和完全不经过K两种情况来讨论:DP[i][j]=min(dp[i][j],dp[i][k]+dp[k][j])#include#include#includeusing namespace std;const int maxv=100;const int INF=999999;int weight[maxv][maxv];int原创 2013-08-08 14:30:32 · 1053 阅读 · 0 评论 -
单源最短路径---Dijkstra 算法--路径还原
#include #include #include #include #include using namespace std;const int maxn=100;const int INF=999999;int pre[maxn];bool visited[maxn];int d[maxn],cost[maxn][maxn],n,m; //n vertexs,1,2,..原创 2013-08-09 13:27:24 · 1335 阅读 · 0 评论 -
poj 2686 Traveling by Stagecoach ---状态压缩DP
题意:给出一个简单带权无向图和起止点,以及若干张马车车票,每张车票可以雇到相应数量的马。点 u, v 间有边时,从 u 到 v 或从 v 到 u 必须用且仅用一张车票,花费的时间为 w(u, v) / ticket[i],其中 w(u, v) 表示边的权值,ticket[i] 表示第 i 张车票可以雇到的马匹数。求从起点到终点花费的最小时间。如果不能到达终点,输出“Impossible原创 2013-08-21 22:15:18 · 1205 阅读 · 0 评论 -
部分和问题---多重部分和问题---动态规划
第一:01部分和(每个数只取一次)给定整数a1、a2、.......an,判断是否可以从中选出若干数,使它们的和恰好为K。输入:n=4a={1,2,4,7}k=13输出:Yes(13=2+4+7)思路:先介绍一种深度优先的搜索方法,从a1顺序决定每个数加或不加,在全部n个数都决定之后在判断和是否为K即可。这个搜索的复杂度是O(2^n).int a[MAXN];原创 2013-08-04 10:30:16 · 2576 阅读 · 1 评论 -
最小生成树---prim算法
我们假设目前得到了一颗树为T,且是有最小权值的,T中的顶点集合为X,然后我们贪心的选取X之外的顶点和T相连的拥有最小权值的边,并把它加到T中,不断进行这个操作,当X=V时,就可以得到一颗生成树,我们可以证明,这棵树就是最小生成树,具体的证明方法这里不再累述(反证法)。代码如下:#include #include #include using namespace std;const原创 2013-08-09 21:06:54 · 1382 阅读 · 0 评论 -
最小生成树---Kruskal算法---挑战程序设计竞赛读书笔记
图和上一篇prim算法一样:http://blog.csdn.net/xiaozhuaixifu/article/details/9864355测试数据也一样。这个算法用到并查集来高效的判断顶点u,v是否属于同一个联通分量。关于并查集:http://blog.csdn.net/xiaozhuaixifu/article/details/9822151代码:#include #原创 2013-08-09 21:53:58 · 1222 阅读 · 0 评论 -
扩展欧几里得算法---Extended Euclidean algorithm
概述欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数。其计算原理依赖于下面的定理:gcd函数就是用来求(a,b)的最大公约数的。gcd函数的基本性质:gcd(a,b)=gcd(b,a)=gcd(-a,b)=gcd(|a|,|b|)公式表述gcd(a,b)=gcd(b,a mod b)证明:a可以表示成a = kb + r,则r原创 2013-08-11 11:01:45 · 2828 阅读 · 0 评论 -
素因子分解 Prime factorization
算术基本定理,又称为正整数的唯一分解定理,即:每个大于1的自然数均可写为质数的积,而且这些素因子按大小排列之后,写法仅有一种方式。例如:,。算术基本定理的内容由两部分构成:分解的存在性:分解的唯一性,即若不考虑排列的顺序,正整数分解为素数乘积的方式是唯一的。第一步:首先用埃氏筛选法构造n以内的素数表,然后再分解:#include #include using namespace原创 2013-08-11 12:49:58 · 5116 阅读 · 0 评论 -
【挑战程序设计竞赛】后缀数组 实现字符串匹配
字符串后缀Suffix 指的是从字符串的某个位置开始到其末尾的字符串字串后缀数组 Suffix Array 指的是将某个字符串的所有后缀按字典序排序之后得到的数组,不过数组中不直接保存所有的后缀子串,只要记录相应的位置就好了。下面的代码使用倍增法来构造后缀数组,该算法的复杂度是 O(n log n)常数因子比较大。基于后缀数组的字符串匹配,我们可以通过二分搜索来完成,算法复杂度是原创 2013-10-07 11:14:34 · 2496 阅读 · 1 评论