zoukankan      html  css  js  c++  java
  • 蓝桥杯 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;
    	}
    

    // 待补充...

    ...
    
  • 相关阅读:
    Linux 防火墙配置
    【存在问题,待修改】SSH 远程登陆
    Hadoop 本地模式安装
    CentOS7 安装 JDK
    JS的DOM操作
    JavaScript
    格式与布局(定位)
    样式表
    表单、内嵌网页
    HTML中的一般标签、常用标签和表格
  • 原文地址:https://www.cnblogs.com/fromneptune/p/12449145.html
Copyright © 2011-2022 走看看