蓝桥杯_垒骰子

 参考博客:

题解:https://blog.csdn.net/lonverce/article/details/45061133

滚动数组:https://blog.csdn.net/niushuai666/article/details/6677982

垒骰子


赌圣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 , 不能通过工程设置而省略常用头文件。

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

       开始被数据大的小惊到了,这么大的数据怎么暴,后来想到了动态规划,但是自己对写动态规划没有信心,因为自己一想要开一个1e9×7的二维数组,大的吓人怎么开的来,自己真的已经将动态规划放下两三个月没有再动过了........

      

#include
#include
#include
#define ll long long

using namespace std;
const ll MOD = 1e9+7;
ll n,m;
bool flag[7][7];
int Comp[7] = {0,4,5,6,1,2,3};
ll dp[2][7];

void Init()
{
   scanf("%I64d%I64d",&n,&m);
    ll a,b;
    memset(flag,false,sizeof(flag));
    memset(dp,0,sizeof(dp));
    for(int i =0 ;i < m;i ++)
    {
        scanf("%I64d%I64d",&a,&b);
        flag[a][b] = 1;
        flag[b][a] = 1;
    }
}
void Solve()
{
    int num = 4;                     //这是每一层中当向上的面确定之后,还能旋转的四种情况
    int a = 0;
    for(int i =1;i <= 6;i ++)        //首先是将所有的第一个不管是什么向上可能的情况都是1
        dp[a][i] = 1;
    for(ll i = 2;i <= n;i ++)       //遍历其他层
    {
        num = (num * 4) % MOD;
        a = 1-a;
        for(int j = 1;j <= 6;j ++)   //循环当前层的情况
        {
            for(int k = 1;k <= 6;k ++) // 当上一层的情况
            {
                if(!flag[Comp[j]][k])
                {
                    dp[a][j] += dp[1-a][k];
                }
            }
            dp[a][j] %= MOD;
        }
    }
    ll ans = 0;
    for(int i =1 ;i <= 6;i ++)
    {
        ans = (ans+dp[a][i])%MOD;
    }
    ans = (ans*num)%MOD;
    printf("%I64d\n",ans);
}

int main()
{
    Init();
    Solve();
    return 0;
}


你可能感兴趣的:(蓝桥杯)