CSP201312-4(有趣的数)(Java100分)

问题描述
  我们把一个数称为有趣的,当且仅当:
  1. 它的数字只包含0, 1, 2, 3,且这四个数字都出现过至少一次。
  2. 所有的0都出现在所有的1之前,而所有的2都出现在所有的3之前。
  3. 最高位数字不为0。
  因此,符合我们定义的最小的有趣的数是2013。除此以外,4位的有趣的数还有两个:2031和2301。
  请计算恰好有n位的有趣的数的个数。由于答案可能非常大,只需要输出答案除以1000000007的余数。
输入格式
  输入只有一行,包括恰好一个正整数n (4 ≤ n ≤ 1000)。
输出格式

  输出只有一行,包括恰好n 位的整数中有趣的数的个数除以1000000007的余数。
样例输入
4
样例输出
3

首先给大家一个运行超时的Java代码:
用深搜做的,20分。

import java.util.Scanner;
public class NumberOfInteresting {
	static long result=0;
	static int n;
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc = new Scanner(System.in);
		n=sc.nextInt();
		dfs("");
		System.out.println(result);
	}
	static void dfs(String s) {
		if(s.length()!=0&&s.charAt(0)=='0') {
			return;
		}
		int t0=s.lastIndexOf('0');
		int t1=s.indexOf('1');
		int t2=s.lastIndexOf('2');
		int t3=s.indexOf('3');
		if(t0!=-1&&t1!=-1&&t0>t1) {
			return;
		}
		if(t2!=-1&&t3!=-1&&t2>t3) {
			return ;
		}
		if(s.length()==n) {
			if(t0!=-1&&t1!=-1&&t2!=-1&&t3!=-1) {
				result=(result+1)%1000000007;
			}
			return ;
		}
		for(int i=0;i<4;i++) {
			String temp=s+String.valueOf(i);
			dfs(temp);
		}
	}
}

一共37行代码,没有写注释。
如果有人不懂dfs(深度优先搜索)是什么,希望你们百度一下,我就不献丑了。
这个题正确的做法有两种:

1–>动态规划:

首先温习一下动态规划的定义:
动态规划(dynamic programming)是运筹学的一个分支,是求解决策过程(decision process)最优化的数学方法。20世纪50年代初美国数学家R.E.Bellman等人在研究多阶段决策过程(multistep decision process)的优化问题时,提出了著名的最优化原理(principle of optimality),把多阶段过程转化为一系列单阶段问题,利用各阶段之间的关系,逐个求解,创立了解决这类过程优化问题的新方法——动态规划。
重点是:每一次决策都基于前一次决策的最优解。
我参考的是:CCF模拟题4-有趣的数 大家也可以看一下,我感觉讲的很不错。
这个讲的也不错 有趣的数
这是我的代码,我没写注释,因为看着人家的理解的,没脸写注释
所以你们还是点进链接看吧

import java.util.*;
public class NumberOfInterestingT {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc = new Scanner(System.in);
		int n=sc.nextInt();
		long a[][]=new long[n][6];
		a[0][0]=1;
		long mod=1000000007;
		//下面是对于任意的一位数,可能出现的情况(已经出现哪几个数)
		/*
		 * 0:2
		 * 1:2 0
		 * 2:2 3
		 * 3:2 0 1
		 * 4:2 0 3
		 * 5:2 0 1 3
		 */
		for(int i=1;i<n;i++) {
			int j=i-1;
			a[i][0]=(a[j][0]*1)%mod;
			a[i][1]=(a[j][0]+a[j][1]*2)%mod;
			a[i][2]=(a[j][0]+a[j][2])%mod;
			a[i][3]=(a[j][1]+a[j][3]*2)%mod;
			a[i][4]=(a[j][1]+a[j][2]+a[j][4]*2)%mod;
			a[i][5]=(a[j][3]+a[j][4]+a[j][5]*2)%mod;
		}
		System.out.println(a[n-1][5]);
		
	}

}

2–>组合数学

直接给大家发参考链接吧,原谅我是个智障。ccf csp 201312-4 有趣的数

还有别的做法,大家自行百度。阿弥陀佛

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值