摘要:
UVA_10518 这个题目想到f(n)=f(n-1)+f(n-2)+1还是比较容易的,但如果能想到是f(n)=2*F(n)-1就不太容易了,在看了UVA的论坛之后我才知道原来可以表示成这个样子,其中F(n)为斐波那契数,有了这个式子是第一步,后面的计算过程倒还不算麻烦。 后来在群里讨论的时候,突然发现S(n)=F(n)+F(n+1)-1,S(n)为斐波那契的前n项和,这时又想到我之前推到的一个结论f(n)=S(n)-F(n-1),发现这个和f(n)=2*F(n)-1是可以转化的,限于当时还不知道S(n)的表达式,所以错过了推出结论的机会。 先说说我推出f(n)=S(n)-F(n)的过程吧,. 阅读全文
摘要:
UVA_10303 不妨设f[i]表示一共有i个元素的时候的二叉搜索树的个数,那么我们依次取1-n作为根就会得到f[n]=f[0]*f[n-1]+f[1]*f[n-2]+…+f[n-1]*f[0],如果我们稍加变形,做一个f[n]=p[n+1]的映射,就会发现f[n]=p[n+1]=p[1]*p[n]+p[2]*p[n-1]+…+p[n]*p[1],这样右边就变成卡特兰数了,于是我们也就算找到了f[n]和卡特兰数的通项p[n]的关系,即f[n]=p[n+1]。 又因为p[1]=1,p[2]=1,所以p[n]=(4n-6)/n*p[n-1],f[n]=(4n-2)/(n+1)*f[n-1]imp 阅读全文
摘要:
UVA_10183 根据通项公式粗略计算一下,我们可以知道10^100内的斐波那契数不会超过600个,因此只需要预处理出这些斐波那契数并扫描一遍即可知道在指定范围内的个数。import java.math.BigInteger;import java.util.Scanner;public class Main { public static void main(String[] args) { Scanner cin = new Scanner(System.in); BigInteger[] f = new BigInteger[600]; ... 阅读全文
摘要:
UVA_10417 如果我们设事件Ai为第1个人带来的是第i类gift,事件B为所有人的gift放一起呈现出题目中给出的每类多少个那种状态。那么P(Ai|B)就对应表示在当前这种状态下第1个人带来的是第i类gift的概率,那么剩下的问题就是把这个概率算出来就好了,然后除以第i类gift的个数就是拿1个第i类的gift且拿成功的概率。 根据条件概率的公式有P(Ai|B)=P(AiB)/P(B),P(AiB)表示事件Ai和B同时发生的概率。由于原始gift状态的子状态个数有限,我们可以指定一个放礼物的顺序(或者拿礼物的顺序)然后进行动规来求各个状态的概率即可。 于是我们不妨规定从第一个人开始,.. 阅读全文
摘要:
SGU_104 我们可以用f[i][j]、p[i][j]分别表示第i行扫描第j个瓶子时的最大值以及取得这个最大值时第i行的花放到了哪个瓶子中。#include<stdio.h>#include<string.h>#define MAXD 110#define INF 0x3fffffffint F, V, f[MAXD][MAXD], v[MAXD][MAXD], p[MAXD][MAXD];void printpath(int i, int j){ if(i != 1) { printpath(i - 1, p[i][j] - 1); printf("... 阅读全文
摘要:
UVA_11176 这个题目一开始打算去求一共有i个W时连续的W不超过j个的情况总数,但后来发现复杂度n^3一直降不下来,后来看了UVA论坛上的提示,终于写出了n^2的算法。 我们设f[i][j]表示到第i场比赛时连续的W不超过j场的概率,那么最后我们只要用j乘以对应的f[N][j]-f[N][j-1]之后求和即可。 接下来我们考虑状态如何转移,对于i=1,显然f[1][0]=1-P,f[1][i]=1(i>=1),而对于任意一个i>1来讲,实际上第i场比赛要么是W,要么是L,如果不影响连续W的场数的话f[i][j]=f[i-1][j],因为这场是W或者L无所谓。那么什么情况下会影 阅读全文