11 2011 档案
摘要:问题描述:给出两个字符串X, Y,求一个串同时是X, Y的子串并且是所有满足条件里的最长的串。分析:题目是一个动态规划问题。设c[i][j]表示 x = {x0, x1, x2, .. xi-1}和 y = {y0, y1, y2, .... yj-1},的最长子序列长度, x, y的字串为 z= {z0, z1, z2, ... zk}。所以有一下规律:当x[i-1] = y[j-1]时,z[k] = x[i-1] = y[j - 1], c[i][j] = c[i-1][j-1] + 1;当x[i-1] != y[j-1] 且 z[k] != x[i-1], c[i][j] = c[i..
阅读全文
摘要:证明:从题目可以知道 A: (1 + x2/1! + x4/2! + ....); B: (1 + x/1! + x2/2! + x3/3! + ...); C:(1 + x2/1! + x4/2! + ....); D: (1 + x/1! + x2/2! + x3/3! + ...);所以有: G(x) = (1 + x2/1! + x4/2! + ....)2 * (1 + x/1! + x2/2! + x3/3! + ...)2;由于泰勒展开式:ex = 1 + x/1! + x2/2! + x3/3! + ...e-x = 1 - x/1! + x2/2! - x3/3! + ...
阅读全文
摘要:指数型生成函数公式(其中一个):指数阶一般求解的问题:已知有n种颜色的求,第1种X1个,第2种X2个,第3种X3个。。。求从中取m个的方案数(组合数)。公式中的ak/k!就是所求的组合数,ak为排列数。代码中:for(i = 1; i < n; i++) { for(j = 0; j <= m; ++j) { for(k = 0; k + j <= m && k <= val[i]; ++k) { c2[j + k] += c1[j]/Factorial(k); } ...
阅读全文
摘要:很裸的生成函数:My Code:#include <iostream>#include <cstring>#include <cstdio>using namespace std;const int N = 100;int c1[N], c2[N];int val[N];int main() { //freopen("data.in", "r", stdin); int i, j, k, t, ans; while(~scanf("%d", &t)) { while(t--) { for(i
阅读全文
摘要:先打表,否则TLEMy Code:#include <iostream>#include <cstring>#include <cstdio>using namespace std;const int N = 32767;int c1[N+1], c2[N+1];int main() { //freopen("data.in", "r", stdin); int n, i, j, k; for(i = 0; i <= N; i++) { c1[i] = 1; c2[i] = 0; } for(i = 2; i &
阅读全文
摘要:/*用并查集做可以,不过总觉得别扭。明明是图论的题嘛。今天在师兄博客里看到这个 解法,用二分限定所取的边的权值。设最大与最小差为lim,最小为low。所以low <= weight <= low + lim;所以,用二分取到lim最小的一个。ps:限定low时需与熬用到hash,否则直接存m个weight会TLE。不能抵达终点输出-1,我晕,因为这个错了好几次。。。T_T*///My Code: 234+MS#include <iostream>#include <cstdio>#include <cstring>#include <set
阅读全文
摘要:从组合数的定义可以知道。C(n, m) = C(n-1, m) + C(n-1, m-1);所以,根据这个公式可以递归的求得组合数,代码如下:long long C(int n, int m) { if(m == 0 || n == 0 || n == 1 || m == n) return 1; if(aug[n][m] != 0) return aug[n][m]; aug[n-1][m] = C(n-1, m); aug[n-1][m-1] = C(n-1, m-1); return aug[n-1][m] + aug[n-1][...
阅读全文
摘要:A题:看错题意了,WA了好几好几次。。。B题:闲的蛋疼多加了一个变量,nnd,我吃饱撑的!!C题:for循环的结束条件写错了,我靠!!!ps:各种错误,各种马虎,rating暴跌,T_T,悲摧啊。看来以后的适应一下晚上做题。。。
阅读全文
摘要:这里可以看成给一个面值为m的钱币,要求将它换成n种不同的面值都为1的钱币,同时要求每种钱币供应的上下限。然后就是生成函数模板了。。。My Code:#include <iostream>#include <cstring>#include <cstdio>using namespace std;const int N = 110;int c1[N], c2[N];int MIN[N], MAX[N];int main() { //freopen("data.in", "r", stdin); int n, m, i,
阅读全文
摘要:没有看到Your program should be able to handle up to 100 coins. WA了n次。。。处理起来有点麻烦,看到大牛的思路是开一个二维数组c[i][j],表示用j个硬币组成大小为i的数。把j限定在100以下(有点dp的感觉,呵呵)。就可以了。详见代码:#include <iostream>#include <cstdio>#include <cstring>using namespace std;const int N = 250;int c1[N+1][N+1], c2[N+1][N+1];int val[5]
阅读全文
摘要:/*用砝码秤重量,按照左物右码的话,砝码的值可以取负。因为砝码最多就一个,所以不许要一般模板里的k 那一重循环,直接去砝码个数为0, 1的两种情况就行。开始把重量取负时那种情况想错了,WA了好几次。。。T_T*///My Code:#include <iostream>#include <cstdio>#include <cstring>using namespace std;const int N = 10007;int c1[N], c2[N];int val[107];int main() { //freopen("data.in"
阅读全文
摘要:貌似跟1171一样的,呃。。。My Code:#include <iostream>#include <cstring>#include <cstdio>using namespace std;const int N = 100;struct node { int val; int num;} a[55];int c1[N], c2[N];int main() { //freopen("data.in", "r", stdin); int t, n, i, j, sum, k, m; while(cin >>
阅读全文
摘要:比1085多了一些变化,见代码。My Code:#include <iostream>#include <cstring>#include <cstdio>using namespace std;const int N = 250007;struct node { int val; int num;} a[55];int c1[N], c2[N];int main() { //freopen("data.in", "r", stdin); int n, i, j, sum, k; while(cin >>
阅读全文
摘要:/*按照母函数的思路,然后模拟三个括号相乘的过程。因为题目已经限定好了硬币只能是1、2、5。所以可以写成:(1 + X + X^2 + ...)(1 + X^2 + X^4 + X^6 + ...)(1 + X^5 + X^10 + X^15 + ...)其中三个括号元素的个数分别是输入的num_1, num_2, num_3。然后就是模拟多项式相乘了。*///ps:代码有点水,一步一步乘的,反正就三个括号,费不了多大劲,^_^//My Code:#include <iostream>#include <cstring>#include <cstdio>us
阅读全文
摘要:母函数模板题,就是稍微改了一下。My Code:#include <iostream>#include <cstring>#include <cstdio>using namespace std;const int N = 307;int c1[N], c2[N];int main() { //freopen("data.in", "r", stdin); int n, i, j, k; while(cin >> n, n) { for(i = 0; i <= n; i++) { c1[i] = 1;
阅读全文
摘要:去你妹的并查集,没纠结死我!按速度排序,然后枚举所有的路,知道find(start) == find(end)结束。然后用最大值减去最小值,求其差,取差最小。Code:#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>using namespace std;const int N = 1024;const int inf = 0x6fffffff;class node {public: int x, y,
阅读全文
摘要:一牛人说:母函数就是把费脑筋的事转换成多项式计算。好吧,我承认母函数用好的话确实很神奇,比如说这个题。可以把n看成无限个可取用的1,2,3,4,5,,,m这些数组成的。然后就是可以写成母函数的形式G(X) = (1 + X^1 + X^2 + X^3 + ...)(1 + X^2 + X^4 + X^6 + ...)(1 + X^3 + X^6 + ...)...然后就是模拟多项式的计算过程。输入的n是多少就计算到几阶,得到的X^n项的系数就是可能的情况数。My Code:#include <iostream>#include <cstdio>#include <
阅读全文
摘要:problem 1:贪心,我二了。。。problem 2:对这题表示无语,我担心快速幂函数会超,所以10^6一次分开幂的,WA了,直接用快速幂函数算就对了,我无语了。。。快速幂函数:int exp_mod(int a,int n,int b){ int t; if(n==0) return 1%b; if(n==1) return a%b; t=exp_mod(a,n/2,b); t=t*t%b; if((n&1)==1) t=t*a%b; return t;}problem 3:母函数模板题。problem 4:按速度排序,然后枚举所有的路,...
阅读全文
摘要:/*发现并查集的应用太巧妙了。。。大体思路:从题中可以看出来如果(i, j)是even的话,sum(i-1) 和 sum(j)的奇偶性相同。(i, j)如果是odd的话则其奇偶行不同。定义奇偶性为朋友,不同则为敌人。这样按照奇偶性分成连个集合。same[i] = {x|sum[x]与sum[i]同奇偶}(即i的朋友集)diff[i] = {x|sum[x]与sum[i]不同奇偶}(即i的敌人集)如果(i, j)是even,则分别合并(same(i-1), same(j))和(dirr[i-1] , diff(j))。如果是odd,则因为不是奇就是偶,所以,一个的朋友和另一个的敌人合并(敌人..
阅读全文
摘要:描述在一个星期三的早上,某同学想用扔硬币的方式来决定是否要去上算法课。他扔n次硬币,如果当中有连续m次以上(含m次)的结果都是正面,那么他就去上课,否则就接着睡觉。(假设每次扔硬币扔出的正反两面的概率都是 0.5。)输入输入的每行有一组数据,分别为n和m(0 <n<= 2000, 0 <m<= 10)。输入以 0 0 结尾。输出对于每组数据,输出他去上课的概率,四舍五入保留小数点后 2 位。 今天队友问我这个题,说是dp的问题。悲摧的开始看错题意了,题目让找连续m次以上的概率。开始思路是建立一个2维dp[i][j],表示仍i次硬币出现j次连续正面朝上的概率。但后来发现实
阅读全文
摘要:/*思路参考大牛,我脑袋被lv踢了,居然想到用数状数组写。。。思路:并查集,先把不许要删的边用并查集合并,然后把需要删的边逆序加入到并查集中。。。。My Code:*/#include <iostream>#include <cstdio>#include <cstring>using namespace std;const int N = 100005;struct node { int s; int e;}g[N];int parent[N];int c[N];int ans[N];int Rank[N];bool vis[N];void init(in
阅读全文
摘要:很裸的单调队列问题,不过O(n)的算法写出来5188+ms,超5s了。。。谁能告诉我500+ms的神级代码是什么。。.T_TMy Code:#include <iostream>#include <cstdio>#include <cstring>using namespace std;const int N = 1000005;struct node { int i; int num;}q[N];int ans[N];int b[N];int main() { //freopen("data.in", "r", st
阅读全文
摘要:话说单调队列!= 优先队列。可怜我捧着算导看了半天优先队列。题意读的很费劲,最后问得师兄。就是给定一个M,然后再给一个序列,求给出的序列里连续M个数中的最大值。最后把这些最大值输出,其实就是很裸的单调队列。然后开始在网上搜有关单调队列的资料,从这里http://www.felix021.com/blog/read.php?1965学会的。其实就是维持队列的单调性,别管是单调增还是单调减。队头元素永远是最列的最小值(或最大值)。 #include <iostream>#include <cstdio>#include <cstring>using namesp
阅读全文
摘要:开始直接暴力,然后果断挂掉。T_T...后来看到DIcuss里有人说用Binary heap。然后就在想怎么用堆优化,想了半天没想到。然后看大牛的思路。鹈鹄灌顶啊!!!思路:先存数列长度的一半+1,然后建立小顶堆。然后输入剩下的元素,如果输入的元素大于堆顶元素,则把堆顶替换掉。再调整一次堆。My Code:#include <iostream>#include <cstdio>#include <algorithm>using namespace std;const int N = 125005;int heap[N];void heap_adjust(in
阅读全文
摘要:思路就是快排+二分查找。有重复的数字,多加了一点小处理。My Code:#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int N = 70005;class node {public: int num; int ord;} a[N];bool cmp(node a, node b){ if(a.num == b.num) return a.ord < b.ord; return a.num
阅读全文
摘要:以前在poj做过,今天有做了下,TLE了。看了一下原来的代码,原来忘了输入的横坐标可能是0的情况了。做下笔记:int lowbit(int i) { return i&(-i);}void add(int i, int val) { //加元素 while(i <= N) { c[i] += val; i += lowbit(i); **i不能是0,否则死循环** }}int sum(int i) { //求和 int s = 0; while(i > 0) { s += c[i]; i -=...
阅读全文
摘要:/*stable_sort()排序时会保留相等元素的位序,而sort()不保留。又学了一点STL,完了,我快无药可救了 T_T*/
阅读全文
摘要:/*我太二了, 上来就暴力,然后TLE两次。然后郁闷的去吃饭,回来一想栈的结构,10分钟AC。有种想撞墙的冲动!*///My Code:#include <iostream>#include <cstdio>#include <cstring>using namespace std;const int N = 200005;char s[N];char str[N];int main() { //freopen("data.in", "r", stdin); int len, top, i; while(cin.get
阅读全文
摘要:code segment assume cs:codemain proc far;repeat: call read call crlf call change call crlf jmp repeatmain endp;read proc near mov bx, 0newchar: mov ah, 1 int 21h sub al, 30h jl exit cmp al, 9d jg exit cbw...
阅读全文
摘要:/*拿到这题确实不知道怎么建图,问师兄,师兄讲了半天我也没听懂,后来看了 Edelweiss大牛的《网络流建模汇总》,第一个就是讲的这道题。大体思路是建立一个很直观的模型,但是复杂度太高,然后根据所找到的规律删边,最后可以得到简单的建图规律:1、从源点S到访问第i个猪圈的第一个人建一条边,容量Ci 就是猪圈里猪的头数,后边如果再有顾客访问第i个猪圈,则从一个访问者到后来访问的顾客建一条边,容量为 +∞ 表示他们之间可以相互联通。2、如果从源点到一名顾客有多条边,则把这些边的合成一条边,容量累加。3、每一个顾客到汇点T建一条边,容量就是顾客要买的猪数。PS:网络流难的不是Dinic,SAP什..
阅读全文
摘要:/*昨晚写把Dinic写错了,一直不出结果,也没调出来,睡觉之前猛然想起来,少了一个break,造成死循环了。今天把那地方改过来,交上去WA。然后又重新敲之,TLE。后来检查了一遍,发现是Floyd写错了,改过后终于过了,发现网络流太容易错了。 思路:1、用Floyd把每个奶牛到每个挤奶机的距离算出来,然后问题就变成了已知c头奶牛到k个挤奶机的距离,求走最远距离的牛走的路程mindis最小是多少。2、然后建网络流模型,每头奶牛和挤奶机都是一个结点。设一个源点s,s到c头奶牛的容量都记为1,k个挤奶机到汇点T的距离都记为m。3、先假设一个mindis的值,然后当奶牛到挤奶机的距离小于min...
阅读全文
摘要:参考郭炜老师课件上的代码。思路是建立一个超级源点和一个超级汇点,先输入的串如果是0000....或02...的形式,则与源点相连,后输入的串如果为1111...则与超级汇点相连。然后拆点,把从入机器前的状态到如机器后的状态看成一个流,流的最大量就是该机器每小时可以加工的元件数。然后用EK的优化——Dinic。思路就是在先用bfs把图中所有的结点标上按遍历的顺序标上层次,这样找到一条增广路径后就不需要退到0号结点,而是推倒所找的增广路径上跟下一个结点的容量是最小容量的那个结点。、Code:#include <iostream>#include <cstring>#incl
阅读全文
摘要:/*很裸的网络流题目,看了两天算导,今天终于A了一道网络流的题目。我的第一道网络流啊。。。^ ^My Code:*/#include <iostream>#include <cstdio>#include <cstring>#include <queue>using namespace std;const int N = 210;const int inf = 0x6fffffff;bool vis[N];int map[N][N];int pre[N];int n, m;int augment() { int v, i, f_min; bool
阅读全文
摘要:这两天搞dp搞的快暴了,想学学网络流。拿过算导来一看,最短路还没整完呢。写了一个用并查集优化的kruskal算法,并查集是用非递归的状态压缩实现的。详见:http://www.cnblogs.com/vongang/archive/2011/07/31/2122763.html。kruskal没有用堆优化,不是我不想,而是实在不会。。。所以直接用sort按权值排了下序,时间复杂度O(n+n*logn)My Code:#include <iostream>#include <cstdio>#include <cstring>#include <algor
阅读全文
摘要:/*昨天看这题,没思路。今天开始做这题,WA到爆了!NND, 把M和N的大小整反了。一遍一遍的盯着我的程序看,苍天啊!浪费生命啊!思路: 转移方程:dp[i][j] = min(dp[i-1][j], dp[i][j+1], dp[i][j-1]) + a[i][j];然后把j从前往后,和从后往前分别走一遍。(只一遍的话实现不了转移方程)另外开一个数组记录到达(i, j),这个位置时过来的方向。最后顺着过来的方向,入队列,输出。我是直接从后往前推的,输出方便。*///My Code:#include <iostream>#include <cstdio>#include
阅读全文
摘要:/*自己想的方法是O(n^2)的,TLE。后来看得解题报告。思路:从后往前找。将输入的序列按s从小到大排序。记录一个输入数据中最大的数MAX;然后从MAX到1。*/while(i = a[n].s) { dp[i] = max(dp[i], dp[T[n].y+1] + 1); n--;}//最后输出dp[1];
阅读全文
摘要:/*dp很明显,参见吴文虎老先生的《程序设计基础》。不过这道题卡内存,直接开1000*1000的数组会超的。然后看到Discuss里有人说dp[2][1000]就可以,然后就按着这个思路写。if(diagonally[i-1][j-1]) dp[1][j] = min (min (dp[0][j], dp[1][j-1]) + 100, dp[0][j-1] + 100*sqrt(2.0));else dp[1][j] = min(dp[0][j], dp[1][j-1]) + 100;每计算出一行将dp[0][...] = dp[1][...];最后输出dp[1][m+1];My C...
阅读全文
摘要:/*题意是求最大子矩阵,表示线代没学好,好在不影响这道题。这题的主要思路就是二维化成一维。把二维数组前一列的元素累加到后边一列上,例如: 0 -2 -7 0 9 2 -6 2-4 1 -4 1-1 8 0 -2处理后就是:0 -2 -9 -99 11 5 7-4 -3 -7 -6-1 7 7 5然后就是dp[i][j] = max(dp[i][j-1], 0) + sum[j];My Code:*/#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>usi
阅读全文
摘要:/*思路:定义dp[i]表示到达第i站的最小花费。所以 dp[i] = min(dp[i-1] + Cx, dp[i-1] + Cx, dp[i-3] + Cx...(直到i 和 (i-x) 两站的距离大于L3);*//*My Code:*/#include <iostream>#include <cstdio>#include <cstring>using namespace std;const int N = 10007;const int inf = 0x7fffffff;int dis[N];int dp[N];int main() { //freo
阅读全文
摘要:为什么别人感觉这是水dp而我总是被dp水呢?还是太弱了。。。思路: 记录[100, 1000)范围内的所有的素数(是素数的每一位)。然后从n = 4往后,定义dp[i][x2][x3], i表示到第i位时,第i-1位为x2, 第i为为x3,此时所包含的情况数。所以有:dp[i][x2][x3] = (dp[i][x2][x3] + dp[i-1][x1][x2])%MOD;最后求和sum(dp[n][x2][x3]);
阅读全文
摘要:Warmup for 2011 Asia Regional Chengdu (Alibaba精英赛题目重现,SJTU命题)——Problem 1004 坑人的题,就是考英语啊。求所有p的和,再加1,就是the minimum budget can not be reached.
阅读全文
摘要:Warmup for 2011 Asia Regional Chengdu (Alibaba精英赛题目重现,SJTU命题)——Problem 1009 /*比赛没做,周六下午做zoj的月赛做的想吐,周日一点心情也没有。今天挺师兄说这题是dp的,就做了做。其实更像拓扑排序,大题思路就是把所有入度为0的点入栈,然后出栈。本体多组数据,WA了一晚上!妹的!*///My Code:#include <iostream>#include <cstdio>#include <cstring>using namespace std;const int N = 1010;l
阅读全文