栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java实现蓝桥杯 垒骰子---dp动态规划+矩阵快速幂

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java实现蓝桥杯 垒骰子---dp动态规划+矩阵快速幂

赌圣atm晚年迷恋上了垒骰子,就是把骰子一个垒在另一个上边,不能歪歪扭扭,要垒成方柱体。
  经过长期观察,atm 发现了稳定骰子的奥秘:有些数字的面贴着会互相排斥!
  我们先来规范一下骰子:1 的对面是 4,2 的对面是 5,3 的对面是 6。
  假设有 m 组互斥现象,每组中的那两个数字的面紧贴在一起,骰子就不能稳定的垒起来。
  atm想计算一下有多少种不同的可能的垒骰子方式。
  两种垒骰子方式相同,当且仅当这两种方式中对应高度的骰子的对应数字的朝向都相同。
  由于方案数可能过多,请输出模 10^9 + 7 的结果。

  不要小看了 atm 的骰子数量哦~

  「输入格式」
  第一行两个整数 n m
  n表示骰子数目
  接下来 m 行,每行两个整数 a b ,表示 a 和 b 数字不能紧贴在一起。

  「输出格式」
  一行一个数,表示答案模 10^9 + 7 的结果。

  「样例输入」
  2 1
  1 2

  「样例输出」
  544

  「数据范围」
  对于 30% 的数据:n <= 5
  对于 60% 的数据:n <= 100
  对于 100% 的数据:0 < n <= 10^9, m <= 36


  资源约定:
  峰值内存消耗 < 256M
  CPU消耗 < 2000ms


  请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

  所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。

  注意: main函数需要返回0
  注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
  注意: 所有依赖的函数必须明确地在源文件中 #include , 不能通过工程设置而省略常用头文件。

  提交时,注意选择所期望的编译器类型。

1.dp数组实现

这种方法只能过8个测试点,因为超时,注意各个数组下标的含义和起始位置。



import java.sql.Array;
import java.util.*;
import java.awt.print.Printable;
import java.lang.*;

public class test2 {

    
    static int[][] md; // 矛盾数组
    
    static long[][] dp; // dp数组
    
    static int[] xd = new int[7]; // 存储的骰子的相对面
    static int mod = 1000000000 + 7;
    static long C=4;
    public static void main(String[] arge) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();// 色子
        int m = scanner.nextInt();// 冲突对
        xd = new int[]{0, 4, 5, 6, 1, 2, 3};
        md = new int[7][7];
        //将md数组(存储冲突数字)
        for (int i = 0; i < 7; i++) {
            for (int j = 0; j < md.length; j++) {
                md[i][j] = -1;
            }
        }
       
        for (int i = 0; i < m; i++) {
            int x = scanner.nextInt();
            int y = scanner.nextInt();
            md[x][y] = 1;
            md[y][x] = 1;
        }

        
        dp = new long[n][8];
        for (int i = 1; i < 7 + 1; i++) {
            dp[0][i] = 1;
        }

        
        for (int i = 1; i < n; i++) {
            C = C * 4 % mod;
            for (int j = 1; j < 7; j++) {
                dp[i][j] = getSum(i, j);
            }
        }
        long sum = 0;
        for (int i = 1; i < 7; i++) {
            sum = (sum + (dp[n-1][i] * C)) % mod;
        }
        System.out.print(sum);
    }

    
    public static long getSum(int i, int j) {
        int sum = 0;
        for (int k = 1; k < 7; k++) {
            if (md[j][xd[k]] != -1) {
                continue;
            }
            sum += dp[i - 1][k];
            sum=sum%mod;
        }
        return sum%mod;
    }
}

2.矩阵快速幂

import java.sql.Array;
import java.util.*;
import java.awt.print.Printable;
import java.lang.*;


class Main2 {
    static Matrixm conflict = new Matrixm(6, 6);

    static int[] xd = new int[7];
    static int mod = 1000000000 + 7;
    static long C = 4;


    public static void main(String[] arge) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();// 色子数
        int m = scanner.nextInt();// 冲突对
        xd = new int[]{0, 4, 5, 6, 1, 2, 3};

        // 冲突数组初始化
        for (int i = 0; i < conflict.m; i++) {
            for (int j = 0; j < conflict.n; j++) {
                conflict.arr[i][j] = 4;
            }
        }

        for (int i = 0; i < m; i++) {
            int x = scanner.nextInt();
            int y = scanner.nextInt();
            conflict.arr[x - 1][xd[y] - 1] = 0;
            conflict.arr[y - 1][xd[x] - 1] = 0;
        }

        conflict = get_power(conflict, n - 1);// 矩阵的n-1个幂×

        long sum = 0;

        for (int hang = 0; hang < conflict.m; hang++) {
            long temp = 0;
            for (int lie = 0; lie < conflict.n; lie++) {
                temp += 4 * conflict.arr[hang][lie];
                temp = temp % mod;
            }
            sum += temp;
            sum = sum % mod;

        }

        System.out.println(sum);

    }


    
    public static Matrixm get_power(Matrixm matrixm, int n) {
        Matrixm unit = new Matrixm(6, 6);//获得一个单位矩阵
        get_identity_martix(unit, 1);
        while (n != 0) {
            if ((n & 1) != 0) {// 如果这是 n的二进制串不是0,既是1,则将unit与A相乘
                unit = get_matrix_multi(unit, matrixm);
            }
            matrixm = get_matrix_multi(matrixm, matrixm);
            n = n >> 1;
        }
        return unit;
    }

    public static Matrixm get_matrix_multi(Matrixm A, Matrixm B) {
        Matrixm temp = new Matrixm(A.m, B.n); // 结果矩阵

        for (int hang = 0; hang < A.m; hang++) { // A矩阵的行
            for (int lie = 0; lie < B.n; lie++) { // B矩阵的列
                long res = 0;
                for (int index = 0; index < A.n; index++) {// 进行相×相加
                    res += (A.arr[hang][index] * B.arr[index][lie]) % mod;
                    res = res % mod;
                }
                temp.arr[hang][lie] = res;
                temp.arr[hang][lie] = temp.arr[hang][lie] % mod;
            }
        }
        return temp;
    }

    
    public static Matrixm get_identity_martix(Matrixm matrixm, int x) {
        //Matrixm unity = new Matrixm(6, 6);
        for (int i = 0; i < 6; i++) {
            for (int j = 0; j < 6; j++) {
                if (i == j) {
                    matrixm.arr[i][j] = x;
                    continue;
                }
                matrixm.arr[i][j] = 0;
            }
        }
        return matrixm;
    }
}


class Matrixm {
    int m;// 行
    int n;// 列

    long[][] arr = new long[6][6];

    public Matrixm(int m, int n) {
        this.m = m;
        this.n = n;
    }
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/769576.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号