标签:
// uva 11357 Matches // // 题目大意: // // 给你n个火柴,用这n个火柴能表示的非负数有多少个,不能含有前导零 // // 解题思路: // // f[i] 表示正好用i根火柴所能表示的整数的个数,则f[i + c[j]] += f[i]; // c[j] 为数字j所需要的火柴的数量,因为当j==0并且i==0的时候,我们不允许这样的 // 转移,因为i=0的时候不允许使用数字0,当n>=6时,再将0加上.我的理解是,当开始可以 // 用0的时候,那么后面的递推,就加上了前导零了,这样并不合法.而0的话我们只要在n>=6 // 的时候加上去就可以啦 // // 感悟: // // 这道题,如果有前导零的话,那么我会这样的刷表法.f[i+c[j]] += f[i],但是 // 没有前导零的话,思索了许久,但是还是没有思路,原来可以在一开始的时候不把0 // 放入,即,不允许i==0的时候用上0,这样在累加的过程中,就不会有前导零,为什么 // 强调两遍呢,我觉得这就是精髓的所在。十分巧妙,继续加油吧~~~FIGHTING import java.util.*; import java.io.*; import java.math.BigInteger; class Main{ public static void main(String[] args){ final int MAX_N = 2020; BigInteger[] f = new BigInteger[2020]; int[] c = {6,2,5,5,4,5,6,3,7,6}; for (int i=1;i<=2000;i++){ f[i] = new BigInteger("0"); } f[0] = new BigInteger("1"); for (int i=0;i<=2000;i++){ for (int j=0;j<10;j++){ if (!(i ==0 && j == 0) && i + c[j] <= 2000) f[i+c[j]] = f[i+c[j]].add(f[i]); } } for (int i=2;i<=2000;i++) f[i] = f[i].add(f[i-1]); int n; Scanner sc = new Scanner(System.in); while(sc.hasNextInt()){ n = sc.nextInt(); System.out.println(f[n].add( (n >= 6 ? new BigInteger("1") : new BigInteger("0")))); } } }
标签:
原文地址:http://www.cnblogs.com/KingJourney/p/4704994.html