I and OI
Past...
摘要: 题意:一个N*M的网格,只能在网格的边上向上或向右走,求从左下角走到右上角的方案数.分析:一共要走N+M步,其中M步向右,N步向上.因此方案数即C(N+M,N).code:var n,m,max,o,ans:int64;begin while not eof do begin readln(n,m); if n+m=0 then halt; max:=n; if m>max then max:=m; ans:=1; o:=max+1; while o<=n+m do begin ans:=int64(ans)*int64(o) div int64(o-max); o:=o+1; e 阅读全文
posted @ 2011-08-10 16:44 exponent 阅读(208) 评论(0) 推荐(0) 编辑
摘要: 题意:求A^B的约数和mod 9901.(0 <= A,B <= 50000000)分析:记f(n)为n的约数和.求f(a^b) mod c.f(n)=∏(pi^(qi+1)-1)/(pi-1)pi为质因子,qi为质因子个数.(pi^(qi+1)-1)/(pi-1)=1+pi+pi^2+......+pi^qi转化为等比数列的和.可以用二分.例如:1+p+p^2+p^3+p^4=p^2+(1+p^3)(1+p)1+p+p^2+p^3+p^4+p^5=(1+p^3)(1+p+p^2)递归进行.code:const mo=9901;var p,q:array[0..20] of lon 阅读全文
posted @ 2011-08-10 16:41 exponent 阅读(670) 评论(0) 推荐(0) 编辑
摘要: 题意:给出N个挂钩,M个砝码,每个挂钩有一个权值,可正可负(相当于天平的左右边).求用M个砝码使天平平衡的方案数(砝码必须全用上).分析:f[i,j]表示用前i个砝码,左右差值为j的方案数.转移见代码.ans=f[m,0].code:const range=8000; r=7500;var f:array[0..21,-range..range] of longint; n,m,k,i,j:longint; p,w:array[0..21] of longint;begin readln(n,m); for i:=1 to n do read(p[i]); readln; for i:=1 t 阅读全文
posted @ 2011-08-10 16:37 exponent 阅读(207) 评论(0) 推荐(0) 编辑
摘要: 题意:现在有4种面值的货币,给出每种货币的数量,求是否能用这4种货币组成总额为P.若存在,则输出该方案.分析:多重背包,数组标记,记录路径.code:type rec=record fa,tot:longint;end;var a:array[1..4] of longint=(1,5,10,25); c,ans:array[1..4] of longint; f:array[0..10001] of boolean; count:array[0..10001] of longint; path:array[0..10001] of rec; i,j,m,cur:longint; functi 阅读全文
posted @ 2011-08-10 16:13 exponent 阅读(376) 评论(0) 推荐(0) 编辑
摘要: 题意:题目给出两列数,为了使两列数的和之间的差距(gap)变小,可以交换对应位置的数字,求出当gap最小的时候,最少的交换次数.分析:用f[i,j]表示处理完前i对数,差为j的最少交换次数.注意到f[i]只跟f[i-1]有关,可以用滚动数组.转移类似于填表.code:var a,b,d:array[0..1001] of longint; f:array[0..1,-6000..6000] of longint; g:array[0..1,-6000..6000] of boolean; n,i,j,pre,now:longint; function min(a,b:longint):long 阅读全文
posted @ 2011-08-10 16:10 exponent 阅读(776) 评论(1) 推荐(1) 编辑
摘要: var f:array[0..101,0..101] of longint; a,b:array[0..101] of longint; dnum,dx,n1,n2,i,j,p,q:longint; function max(a,b:longint):longint; begin if a>b then exit(a); exit(b); end;begin readln(dnum); for dx:=1 to dnum do begin fillchar(f,sizeof(f),0); readln(n1,n2); for i:=1 to n1 do read(a[i]); readl 阅读全文
posted @ 2011-08-10 16:04 exponent 阅读(297) 评论(0) 推荐(0) 编辑
摘要: 题意:判断最小生成树是否唯一.分析:先求出一棵最小生成树,记下最小权值为W0.然后枚举树上的每条边,去掉以后再求一次最小生成树,只要出现权值等于W0,那么最小生成树一定不唯一.因为范围小,所以这样的算法可以过.还有更优的算法.code:type node=record u,v,w:longint; bo:boolean;end;const oo=100000000;var e:array[0..11000] of node; mst,f:array[0..110] of longint; min,d,datanum,n,m,o,now:longint; bool:boolean; proced 阅读全文
posted @ 2011-08-10 16:00 exponent 阅读(861) 评论(0) 推荐(0) 编辑
摘要: 题意:中文描述.分析:havel定理的应用.havel定理的简介:给定一个非负整数序列{d1,d2,...dn},若存在一个无向图使得图中各点的度与此序列一一对应,则称此序列可图化。进一步,若图为简单图,则称此序列可简单图化。可图化的判定比较简单:d1+d2+...dn=0(mod2)。关于具体图的构造,我们可以简单地把奇数度的点配对,剩下的全部搞成自环。可简单图化的判定,有一个Havel定理,是说: 我们把序列排成不增序,即d1>=d2>=...>=dn,则d可简单图化当且仅当d'=(d2-1, d3-1, ... d(d1+1)-1, d(d1+2), d(d1+ 阅读全文
posted @ 2011-08-10 15:53 exponent 阅读(809) 评论(0) 推荐(0) 编辑
摘要: 题意:给定一棵树,问删除哪个点,使余下的各个子树结点个数的最大值最小.分析:先DFS一次,求出以每个节点为根的子树的节点个数s[i].设f[i]表示去掉i后,余下的各个子树结点个数的最大值.f[i]=max(n-s[i],max{s[j]}). (j为i的儿子).这样再DFS一次,求出max{f[i]}即为答案.code:type edge=record v,n:longint;end;const maxn=20001; oo=100000000;var e:array[0..maxn*2] of edge; h,s,f:array[0..maxn] of longint; vis:array 阅读全文
posted @ 2011-08-10 15:49 exponent 阅读(867) 评论(0) 推荐(0) 编辑
摘要: 题意:就是求最长上升子序列.分析:N^2DP会超时,用NlogN的算法.code:var a:array[0..40001] of longint; datanum,d,n,i,p,top,num:longint; procedure find(key,l,r:longint); var mid:longint; begin if l=r then begin p:=l; exit; end; mid:=(l+r)>>1; if a[mid]>key then find(key,l,mid) else find(key,mid+1,r); end;begin readln(d 阅读全文
posted @ 2011-08-10 15:43 exponent 阅读(143) 评论(0) 推荐(0) 编辑
摘要: 题意:N组学生.一个学生能同时加入不同的组.同一组的学生会同时感染病毒.现在0号的学生感染了病毒,问一共有多少个人感染病毒.分析:并查集.将同一组的学生合并.这样有交集的组也被合并.最后只要求出0号所在的集合大小即可.code:var f:array[0..30000] of longint; n,m,i,j,k,u,v,fu,fv,fx,ans:longint; function getf(x:longint):longint; begin if f[x]<>x then f[x]:=getf(f[x]); exit(f[x]); end;begin while not seek 阅读全文
posted @ 2011-08-10 15:41 exponent 阅读(228) 评论(0) 推荐(0) 编辑
摘要: 题意:求N阶乘的位数.分析:用斯特林近似公式求阶乘.一个数Num的位数=[lg(Num)]+1.斯特林近似公式:N!≈(2*pi*N)^0.5*(n/e)^n.于是N!的位数=ln((2*pi*N)^0.5*(n/e)^n)/ln(2).用一些对数变换防止溢出.code:const e=2.71828182; pi=3.1415926; ln10=ln(10); lnpi=ln(pi); ln2=ln(2);var datanum,d,n:longint; ans1,ans2,lnn:extended;begin readln(datanum); for d:=1 to datanum do 阅读全文
posted @ 2011-08-10 15:34 exponent 阅读(320) 评论(0) 推荐(0) 编辑
摘要: 题意:将一个表达式化简,将多余的括号去掉.分析:先将表达式转为后缀表达式,再转回中缀表达式,这样多余的括号就去掉了.code:var snum:set of char; n,q:longint; s:ansistring; function grade(ch:char):longint; begin grade:=-1; case ch of '+':exit(1); '-':exit(1); '*':exit(2); '/':exit(2); '(':exit(0); end; end; function mid 阅读全文
posted @ 2011-08-10 15:27 exponent 阅读(431) 评论(0) 推荐(0) 编辑
摘要: 题意:整数划分问题,将整数N分为K份,每份都不为0.求方案数.分析:DP,f[i,j]表示整数I,分为J份的方案数.分两类进行转移:1.分出来的j份中没有含1的,f[i,j]=f[i-j,j].2.分出来的j分中含有1,f[i,j]=f[i-1,j-1];合起来f[i,j]=f[i-1,j-1]+f[i-j,j];特殊的f[i,i]=1.code:var f:array[0..201,0..201] of int64; n,k,i,j:longint;begin for i:=1 to 201 do f[i,i]:=1; for i:=2 to 201 do for j:=1 to i-1 d 阅读全文
posted @ 2011-08-10 15:22 exponent 阅读(293) 评论(0) 推荐(0) 编辑
摘要: 题意:现在需要价格总额为cash的钱,有n种面值的钱币,每种钱币的数目为n[i],面值为d[i],求在小于或等于所需价格总额的情况下所能组成的最大价值.分析:多重背包,数组标记.code:var f:array[0..120000] of boolean; count:array[0..120000] of longint; v,t:array[0..120] of longint; n,m,i,j,ans:longint;begin while not eof do begin read(m,n); if (n=0)and(m=0) then halt; fillchar(f,sizeof( 阅读全文
posted @ 2011-08-10 15:05 exponent 阅读(279) 评论(0) 推荐(0) 编辑
摘要: 题意:有6种面值的货币,保证最小面值是1.可加可减,求出分别组成1~100金额的最少货币数.并求出它们的平均值和最大值.分析:有负权的完全背包,下界开大,注意处理负权即可.code:const oo=33686018; maxn=20000;var datanum,d,o,i,j,ans,max:longint; a:array[1..6] of longint; f:array[0..maxn] of longint; function min(a,b:longint):longint; begin if a>b then exit(b); exit(a); end;begin rea 阅读全文
posted @ 2011-08-10 15:02 exponent 阅读(417) 评论(0) 推荐(0) 编辑
摘要: 题意:要求设计这样一个数据结构,支持下列操作1.add(x,y,a).对二维数组的第x行,第y列加上a.2.sum(l,b,r,t).求所有满足l<=x<=r,b<=y<=t,的数组元素的和.显然,二维树状数组满足这些要求.code:var c:array[0..1025,0..1025] of longint; opt,n,x,y,a,l,b,r,t:longint; function lowbit(i:longint):longint; begin lowbit:=i and (i xor (i-1)); end; procedure change(x0,y0,a: 阅读全文
posted @ 2011-08-10 13:18 exponent 阅读(1168) 评论(0) 推荐(0) 编辑
摘要: 题意:给出n个村庄的坐标,要求建m个邮局,使得所有村庄到离其最近的邮局的距离之和最小.分析:DP.f[i,j]表示前i个村庄建j个邮局的最小代价.f[i,j]=min{f[k,j-1]+cost[k+1,i]}cost[l,r]表示在l,r之间建一个邮局,代价是多少.可以O(N^3)地预处理出来.总复杂度为O(N^3).code:const oo=100000000;var f,dis:array[0..310,0..310] of longint; p:array[0..310] of longint; n,m,i,j,k,now,mid:longint; function min(a,b: 阅读全文
posted @ 2011-08-10 13:12 exponent 阅读(726) 评论(0) 推荐(0) 编辑
摘要: 题意:求最少添加多少个括号可以使得原序列成为合法的括号序列,并输出这个合法的括号序列.分析:DP,记录路径.用f[i,j]表示i~j之间的序列至少添加多少个括号.显然,f[i,i]=1.1.f[i,j]=f[i+1,j-1] (s[i],s[j]可以配对)d[i,j]=-1;2.f[i,j]=min{f[i,k]+f[k+1,j]} (i<=k<=j-1)d[i,j]=k;(k是f[i,j]的决策点)方案输出见代码.code:const oo=10000000;var f,d:array[0..110,0..110] of longint; s:array[0..110] of c 阅读全文
posted @ 2011-08-10 13:02 exponent 阅读(490) 评论(0) 推荐(0) 编辑
摘要: 题意:对于一个点i,设f(i)=max{mindis[i,j]} (j≠i).其中mindis是各个点对之间的最短路.求min{f(i)} (1<=i<=n).分析:floyd求出最短路即可.code:var person,time,n,i,j,k,p,min,max,mini,minperson:longint; map:array[0..110,0..110] of longint; f:boolean;begin readln(n); while n<>0 do begin fillchar(map,sizeof(map),1); for i:=1 to n do 阅读全文
posted @ 2011-08-10 12:54 exponent 阅读(303) 评论(0) 推荐(0) 编辑