现在的位置: 首页 > 综合 > 正文

UVA 10862 Connect the Cable Wires

2013年02月06日 ⁄ 综合 ⁄ 共 1204字 ⁄ 字号 评论关闭

UVA_10862

    我们不妨设f(n)为n个方块时情况的种数,那么我们不妨从f(n-1)入手,在后面添加第n个方块,看看一共有多少种添加进去的方式。

    为了讨论的方便,我们对第n个方块标号为1,第n-1个标号为2,等等,然后画出下面这个图。

                   (圆圈)

    方块n    ……    方块3    方块2    方块1

    首先,方块1是可以在f(n-1)的基础之上连上圆圈,这样就有f(n-1)情况了,其次方块1可以在f(n-1)的基础之上连上方块2,这样就又有了f(n-1)种情况。

    当然,还有最后一种情况,就是方块1既和方块2连在一起,又和圆圈连在一起,这时f(n-1)的图里必须删掉一条边,但如果我们从删边的角度入手的话,这一部分就不好算了。其实这时我们可以很明显的知道,方块2是不可能再和圆圈连一条边了,否则就成了环,于是我们就happy了,因为这样方块1和方块2不就可以看做一个整体了么?并且这个整体必须和圆圈有一条边。

    那么看成整体之后就简单了呀,就好比刚刚添加方块1一样,分类去算呗,我们不妨把这个整体叫12。与添加1不同的是,12必须和圆圈连一条边,那么就只剩两种情况了,一种情况是12和3之间没有边,这一部分自然就是f(n-2)种情况,另外一种就是12和3之间有一条边。这时明显就成递归了呀,因为如果12和3之间有一条边的话,3必然不能和圆圈相连,这样12和3不就又可以看成一个整体了么?

    最后再说下递归的边界,假如现在1~n-1是一个整体了,那么一部分情况是f(1),另外一部分情况就是1~n-1和n之间有条边,后者只有1种情况。那么我们就可以把递推公式写出来了,f(n)=2*f(n-1)+f(n-2)+…+f(1)+1,注意这时n是大于1的。之后我们化简一下,写出f(n-1)=2*f(n-2)+f(n-3)+…+f(1)+1,注意这时n是大于2的。两式作差就可以得到f(n)=3*(n-1)-f(n-2)(n>2)。

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[2010];
f[1] = new BigInteger("1");
f[2] = new BigInteger("3");
for(int i = 3; i <= 2000; i ++)
f[i] = f[i - 1].multiply(new BigInteger("3")).add(f[i - 2].negate());
int N;
for(;;)
{
N = cin.nextInt();
if(N == 0)
break;
System.out.println(f[N]);
}
}
}


抱歉!评论已关闭.