【蓝桥杯】第六届-9-垒骰子

题目

赌圣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

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

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.7及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。

分析

经过仔细的分析,会发现这是一道DP动态规划问题,可以先假设骰子的侧面是固定的,然后通过举例如下:
输入:
2 1
1 2
此时的dp矩阵数组如下:

|      | 1    | 2    | 3    | 4    | 5    | 6    |
| ---- | ---- | ---- | ---- | ---- | ---- | ---- |
| 二层  | 5    | 5    | 6    | 6    | 6    | 6    |

输入:
3 1
1 2
此时的dp矩阵数组如下:

|      | 1    | 2    | 3    | 4    | 5    | 6    | sum  |
| ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- |
| 二层  | 5    | 5    | 6    | 6    | 6    | 6    |34    |
| 三层  | 28   | 28   | 34   | 34   | 34   | 34   |192   |

具体变换过程如下:

|      | 1    | 2    | 3    | 4    | 5    | 6    | sum  |
| ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- |
| 1    | 5    | 5    | 6    | 6    | -    | 6    |28    |
| 2    | 5    | 5    | 6    | -    | 6    | 6    |28    |
| 3    | 5    | 5    | 6    | 6    | 6    | 6    |34    |
| 4    | 5    | 5    | 6    | 6    | 6    | 6    |34    |
| 5    | 5    | 5    | 6    | 6    | 6    | 6    |34    |
| 6    | 5    | 5    | 6    | 6    | 6    | 6    |34    |

从中分析可以发现当n=3时,每种情况都使用到了n=2时的数据,出现重叠子问题与最优子结构,于是用DP来求解。同时,为了节省空间,可以使用滚动DP来替代DP
最后,由于侧面方案数为4,那么在乘以4^n就可以了就可得到最终解。

代码

import java.math.BigInteger;
import java.util.Scanner;

public class Nine {
    public static final int MOD = 1000000007;
    public static int init[] = { -1, 4, 5, 6, 1, 2, 3 }; // 骰子对面
    public static boolean conflict[][] = new boolean[7][7]; // 冲突

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        for (int i = 0; i < m; i++) {
            int a = sc.nextInt();
            int b = sc.nextInt();
            conflict[a][b] = conflict[b][a] = true;
        }

        // dp[i][j] 代表,i个骰子且最顶面是j的情况种数 并且使用了滚动dp,否则会超空间
        BigInteger dp[][] = new BigInteger[2][7];
        int e = 0;
        for (int i = 1; i < 7; i++)
            dp[e][i] = BigInteger.ONE;

        for (int i = 2; i <= n; i++) {
            e = 1 - e;
            for (int j = 1; j < 7; j++) {
                dp[e][j] = BigInteger.ZERO;
                for (int k = 1; k < 7; k++) {
                    if (!conflict[init[j]][k])
                        dp[e][j] = dp[e][j].add(dp[1 - e][k]).mod(
                                new BigInteger(MOD + ""));
                    System.out.println("dp["+e+"]["+j+"]="+dp[e][j]);
                }
            }
        }
        System.out.println("e="+e);
        BigInteger sum = BigInteger.ZERO;
        for (int i = 1; i < 7; i++) {
            sum = sum.add(dp[e][i]).mod(new BigInteger(MOD + ""));
        }
        System.out.println("sum = "+sum);
        System.out.println(sum.multiply(quickpow(4, n)).mod(
                new BigInteger(MOD + "")));
    }

    // 快速幂
    static BigInteger quickpow(int n, int m) {
        BigInteger n1 = new BigInteger(n + "");

        BigInteger t = BigInteger.ONE;
        while (m > 0) {
            if ((m & 1) == 1)
                t = t.multiply(n1).mod(new BigInteger(MOD + ""));
            n1 = n1.multiply(n1).mod(new BigInteger(MOD + ""));
            m >>= 1;
        }
        return t;
    }
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容

  • 1、三角形面积 如【图1】所示。图中的所有小方格面积都是1。那么,图中的三角形面积应该是多少呢? 请填写三角形的面...
    Jdqm阅读 1,673评论 0 4
  • 简介 用简单的话来定义tcpdump,就是:dump the traffic on a network,根据使用者...
    保川阅读 5,941评论 1 13
  • 垒骰子 赌圣atm晚年迷恋上了垒骰子,就是把骰子一个垒在另一个上边,不能歪歪扭扭,要垒成方柱体。经过长期观察,at...
    徐森威阅读 1,678评论 2 1
  • 在学校的日子,天天惦记着假期。 假期到来了,又开始在家遭嫌弃。 于是,想出去打工的念头就出来了。 既可以偷偷出去疯...
    木三米阅读 462评论 0 4
  • 刀光不依不饶。 跌进谁的怀抱。 午夜战场大漠荒烟。 如狂草。 霜降。 满城萧条。 冷了长亭短桥。 眉间朱砂。 乱世...