Under my umbrella.

SKII

Less is more.

蓝桥杯 2015年 第六届 垒骰子(JAVA)

蓝桥杯 2015年 第六届 垒骰子(JAVA)

方法一:简单的dfs思路,只能得30%的分。

需要注意的是:除第一层外底层筛子都有四个面可选,所以diceNum==n时ans要+4,

并且第一层也有四个面可选,所以最后要乘以4

实际最多算到n==12左右, 再往后就极慢了

package provincial_2015B;

import java.util.Scanner;

public class Nine {
	private static int[] dice;
	private static int[][] exclusion;
	private static int n;
	private static int ans = 0;
	
	static {
		dice = new int[6+1];
		dice[1] = 4;
		dice[2] = 5;
		dice[3] = 6;
		dice[4] = 2;
		dice[5] = 2;
		dice[6] = 3;
		
		exclusion = new int[6+1][6+1];
	}
	
	private static void dfs(int up, int diceNum) {
		if(diceNum == n) {
			ans += 4;
			return ;
		}
		
		for(int nextUp = 1; nextUp < 7; nextUp++) {
			if(exclusion[nextUp][dice[up]]==1) 
				continue;
			dfs(nextUp, diceNum+1);
		}
	}
	
	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		n = scan.nextInt();
		int m = scan.nextInt();
		for(int i = 0; i < m; i++) {
			int a = scan.nextInt();
			int b = scan.nextInt();
			exclusion[a][b] = 1;
			exclusion[b][a] = 1;
		}
		
		for(int i = 1; i < 7; i++) {
			dfs(i, 1);
		}
		
		System.out.println(ans*4);
	}
}

方法二: 动态规划之记忆型递归

比第一种快的多, 可以在之前那个算法算12的时间下算到70, 但还是达不到60%的数据

package provincial_2015B;

import java.util.Arrays;
import java.util.Scanner;

public class Nine {
	private static int[] dice;
	private static int[][] exclusion;
	private static int n;
//	private static int ans = 0;
	private static int[][] visited;
	
	static {
		dice = new int[6+1];
		dice[1] = 4;
		dice[2] = 5;
		dice[3] = 6;
		dice[4] = 2;
		dice[5] = 2;
		dice[6] = 3;
		
		exclusion = new int[6+1][6+1];
	}
	
//	private static void dfs(int up, int diceNum) {
//		if(diceNum == n) {
//			ans += 4;
//			return ;
//		}
//		
//		for(int nextUp = 1; nextUp < 7; nextUp++) {
//			if(exclusion[nextUp][dice[up]]==1) 
//				continue;
//			dfs(nextUp, diceNum+1);
//		}
//	}
	
	private static int dp(int up, int diceNum) {
		if(diceNum == n) {
			return 4;
		}
		if(visited[up][diceNum]!=0)
			return visited[up][diceNum];
		
		int ans = 0;
		for(int nextUp = 1; nextUp < 7; nextUp++) {
			if(exclusion[nextUp][dice[up]]==1) 
				continue;
			ans += dp(nextUp, diceNum+1);
		}
		
		visited[up][diceNum] = ans; 
		return ans;
	}
	
	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		n = scan.nextInt();
		int m = scan.nextInt();
		for(int i = 0; i < m; i++) {
			int a = scan.nextInt();
			int b = scan.nextInt();
			exclusion[a][b] = 1;
			exclusion[b][a] = 1;
		}
		
		visited = new int[6+1][n+1];
		int ans = 0;
		for(int i = 1; i < 7; i++) {
			ans += 4*dp(i, 1);
		}
		
		System.out.println(ans);
	}
}

方法三: 标准动态规划

比之前得都快很多, 能跑出来80%

package provincial_2015B;

import java.util.Scanner;

public class Nine_case2 {
	private static int[] dice;
	private static int[][] conflict;
	private static int MOD = 1000000007;
	
	static {
		dice = new int[6+1];
		dice[1] = 4;
		dice[2] = 5;
		dice[3] = 6;
		dice[4] = 2;
		dice[5] = 2;
		dice[6] = 3;
		
		conflict = new int[6+1][6+1];
	}
	
	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		int n = scan.nextInt();
		int m = scan.nextInt();
		for(int i = 0; i < m; i++) {
			int a=scan.nextInt();
			int b=scan.nextInt();
			conflict[a][b]=1;
			conflict[b][a]=1;
		}
		
		int[][] dp = new int[n+1][6+1];
		for(int i = 0; i < 6+1; i++) 
			dp[0][i]=1;
		
		for(int i = 1; i < n; i++) {
			for(int j = 1; j < 7; j++) {
				for(int k = 1; k < 7; k++) {
					if(conflict[dice[j]][k]==1) 
						continue;
					dp[i][j]=
						(dp[i][j]+dp[i-1][k])%MOD;
				}
			}
		}
		long ans=0;
		for(int i = 1; i < 7; i++)
			ans=(ans+dp[n-1][i])%MOD;
		
		System.out.println(ans*4*4);
	}
}

终极方法: 矩阵快速幂

顺便科普快速幂运算

public static long quickPower(int a, int b, int mod) {
		// a^b % MOD
		// 任何数对1取模得0
		if(mod==1) return 0;
		
		long ans = 1;
		while(b!=0) {
			if((b&1)==1) ans=(ans*a)%mod;
			a=(a*a)%mod;
			b>>=1;
		}
		
		return ans;
	}

// 待补充...

...
posted @ 2020-03-09 15:51  NLYang  阅读(176)  评论(0编辑  收藏  举报