其他分享
首页 > 其他分享> > 汤汤的女装

汤汤的女装

作者:互联网

来自某大学计算机院赛原题,状态转移矩阵DP   7-6 汤汤の女装

       众所周知,16级的竞赛带头人汤汤是个女装爱好者,经常cosplay成玩家喜闻乐见的女性角色出现在动漫展上,因为其妖娆的身姿、魅惑的神情,经常能够博得全场好评,那些看客无不发出awsl、我又好了之类的惊呼。16级的学习の光——郑一花一直很想得到汤汤的女装珍藏,可惜汤汤视若珍宝,说什么也不肯。终于在一个月黑风高的白天,一花设计给汤汤吃狗粮,狗粮是给菜狗吃的,比如LJL这样的单身菜狗,汤汤只是一个平平无奇、爱好女装的现充,哪里能吃得这种东西。汤汤被毒进医院之后,他的一票后宫都跟着进去陪护了,一花乘虚而入,万万没想到要打开汤汤的女装柜需要输入相应的密码。
       所幸,他抓来了正在给汤汤扫地的LJL,并承诺支付他三个月的狗粮,LJL哪里禁得住这样的诱惑。但是他也只知道密码表示的是邪恶数的个数,每个邪恶数都对应汤汤一个邪恶形态,每个邪恶数具有如下性质:
       1.一共有n位,每位都是奇数。鲁迅曾经说过:奇变偶不变、符号看象限,全部都用奇数组成的密码反映的正是汤汤邪恶的本质。
       2.其中3、5、7的出现次数都是偶数次,据说这个奇怪的设定是因为汤汤对于某个传奇教练发型的致敬,这边按下不表。
       一花心领神会,解出密码之后将汤汤多年的积蓄席卷一空,那么他到底是怎么做到的呢。 给定邪恶数位数n,邪恶数有多少个?换言之,汤汤到底有多少种不同的邪恶形态呢?

输入格式:

每个测试点只输入一个n(1<=n<=10^18),表示邪恶数的位数。

输出格式:

输出邪恶数的个数,因为数字太大,请对10^9+7取模

输入样例1:

1
 

输出样例1:

2
 

输入样例2:

2
 

输出样例2:

7
 

提示:

如果邪恶数只有1位、满足条件的只有1和9 如果邪恶数有两位,满足条件的有33、55、77、19、91、11、99

 

解题思路

(1)对于i-1的所有方案,只需在最后加上5个奇数,再加以判断就可以得到第i个状态
这样也就说明要记录的不仅仅是成功的方案,还要记录加入奇数可以转移至成功方案的所有方案


(2)3,5,7各取奇偶个,总共有2^3=8种情况
其中第1种情况记录为,偶偶偶也就是bi[0]所储存的


(3)A[i][j]表示从状态i转移到状态j有几种方案
题解没有错!!!这句话很重要
第i个状态是被消去的状态,最后留下来的是j


(4)bi表示总位数为i位时,所拥有的全部方案
容易得到b1[0]=2;
状态转移矩阵:bn=b1*A^(n-1)

#include<cstdio>
#include<vector>
using namespace std;
typedef long long ll;

typedef vector<ll> vec;
typedef vector<vec> mat;
//简化声明一个矩阵

const ll md = 1e9 + 7;
//矩阵乘法
mat mul(const mat& a, const mat& b) {
    mat res(a.size(), vec(b[0].size()));
    //初始化res,取a的行,每行有b[0].size()个 0、
    //易得,行==列

    //矩阵乘法
    for (int i = 0; i < a.size(); ++i) {
        for (int k = 0; k < b.size(); ++k) {
            for (int j = 0; j < b[0].size(); ++j) {
                res[i][j] = (res[i][j] + a[i][k] * b[k][j] % md) % md;
            }
        }
    }
    return res;
}

//矩阵快速幂
mat Quickpow(mat a, ll n) {
    mat res(a.size(), vec(a.size()));
    //初始化一个值都为0的方阵
    for (int i = 0; i < a.size(); ++i)res[i][i] = 1;
    //单位矩阵E
    while (n) {
        if (n & 1)res = mul(res, a);
        a = mul(a, a);
        n >>= 1;
    }
    return res;
}
int main() {
    ll n;
    scanf("%lld", &n);
    mat a = {{2, 1, 1, 0, 1, 0, 0, 0},
   {1, 2, 0, 1, 0, 1, 0, 0},
   {1, 0, 2, 1, 0, 0, 1, 0},
   {0, 1, 1, 2, 0, 0, 0, 1},
   {1, 0, 0, 0, 2, 1, 1, 0},
   {0, 1, 0, 0, 1, 2, 0, 1},
   {0, 0, 1, 0, 1, 0, 2, 1},
   {0, 0, 0, 1, 0, 1, 1, 2} };
//求出矩阵A的n-1次方
    a = Quickpow(a, n - 1);
//状态转移方程矩阵bn=b1*A^(n-1)
//bn[0]为所求答案,bn的第0行,乘以A的第0列
    ll ans = (((2 * a[0][0] % md + a[1][0]) % md + a[2][0]) % md + a[4][0]) % md;
    printf("%lld", ans);
}

 

 

 

 

 

标签:md,mat,res,汤汤,邪恶,女装,size
来源: https://www.cnblogs.com/ghostlx/p/13780128.html