当前位置:网站首页>Base dice (dynamic programming + matrix fast power)
Base dice (dynamic programming + matrix fast power)
2022-07-06 16:25:00 【AC__ dream】

My first idea when I see this topic is dynamic programming , set up dp[i][j] It means that we enumerated i Dice with j Number of alternatives , Then it is obviously initialized to dp[1][j]=4(j=1~6)( Different side directions are calculated according to different schemes ), The recursive process is very simple , Namely dp[i][j]=vis[(j+2)%6+1][k]*dp[i-1][k](k=1,2,3,4,5,6),(j+2)%6+1 Representative is j The opposite number of , Analysis I think this topic is finished , Then write the code and run it. The result is also right , Timeout was found after submission , At this time, the data range is 1E9, Linear DP It's impossible to do it , Generally, we need to use the fast power of matrix to optimize , With dp[i][j]=vis[(j+2)%6+1][k]*dp[i-1][k] This recursion , We can get the recursive matrix 
vis[i][j]=0 perhaps 4, if 0 explain i and j Can't be adjacent , Otherwise, it corresponds to four schemes ( The side order is arbitrary ), Initial value of answer matrix f(1,j)=4(j=1,2,3,4,5,6) , Follow this process to solve the matrix fast power
Here is the code :
Code that does not use fast power recursion ( Timeout code ):
#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
#include<map>
#include<cmath>
#include<queue>
using namespace std;
typedef long long ll;
const int N=1003,mod=1e9+7;
ll dp[N][7];//dp[i][j] By i Dice form the top of j Number of alternatives
int vis[7][7];
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=6;i++)
for(int j=1;j<=6;j++)
vis[i][j]=4;
while(m--)
{
int u,v;
scanf("%d%d",&u,&v);
vis[u][v]=vis[v][u]=0;
}
for(int i=1;i<=6;i++)
dp[1][i]=4;
for(int i=2;i<=n;i++)
{
for(int j=1;j<=6;j++)
for(int k=1;k<=6;k++)
dp[i][(j+2)%6+1]=(dp[i][(j+2)%6+1]+dp[i-1][k]*vis[j][k])%mod;
}
ll ans=0;
for(int i=1;i<=6;i++)
ans+=dp[n][i];
printf("%lld",ans);
return 0;
} The following is the code of matrix fast power recursion (AC Code ):
#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
#include<map>
#include<cmath>
#include<queue>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
int vis[7][7];
void mul(ll ans[][7],ll a[][7],ll b[][7])
{
ll t[7][7]={0};
for(int i=1;i<=6;i++)
for(int j=1;j<=6;j++)
for(int k=1;k<=6;k++)
t[i][j]=(t[i][j]+a[i][k]*b[k][j])%mod;
memcpy(ans,t,sizeof t);
}
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=6;i++)
for(int j=1;j<=6;j++)
vis[i][j]=4;
while(m--)
{
int u,v;
scanf("%d%d",&u,&v);
vis[u][v]=vis[v][u]=0;
}
ll t[7][7]={
{0,0,0,0,0,0,0},
{0,vis[1][4],vis[1][5],vis[1][6],vis[1][1],vis[1][2],vis[1][3]},
{0,vis[2][4],vis[2][5],vis[2][6],vis[2][1],vis[2][2],vis[2][3]},
{0,vis[3][4],vis[3][5],vis[3][6],vis[3][1],vis[3][2],vis[3][3]},
{0,vis[4][4],vis[4][5],vis[4][6],vis[4][1],vis[4][2],vis[4][3]},
{0,vis[5][4],vis[5][5],vis[5][6],vis[5][1],vis[5][2],vis[5][3]},
{0,vis[6][4],vis[6][5],vis[6][6],vis[6][1],vis[6][2],vis[6][3]},
};
ll ans[7][7]={
{0,0,0,0,0,0,0},
{0,1,0,0,0,0,0},
{0,0,1,0,0,0,0},
{0,0,0,1,0,0,0},
{0,0,0,0,1,0,0},
{0,0,0,0,0,1,0},
{0,0,0,0,0,0,1},
};
n--;
while(n)
{
if(n&1) mul(ans,ans,t);
n>>=1;
mul(t,t,t);
}
ll sum=0;
for(int i=1;i<=6;i++)
for(int j=1;j<=6;j++)
sum=(sum+ans[i][j]*4)%mod;
printf("%lld",sum);
return 0;
}边栏推荐
猜你喜欢

QT模拟鼠标事件,实现点击双击移动拖拽等

QT有关QCobobox控件的样式设置(圆角、下拉框,向上展开、可编辑、内部布局等)

C language learning notes

QT implementation window gradually disappears qpropertyanimation+ progress bar

605. Planting flowers

Codeforces Round #797 (Div. 3)无F

力扣:第81场双周赛

D - function (HDU - 6546) girls' competition

树莓派4B安装opencv3.4.0

QWidget代码设置样式表探讨
随机推荐
QT realizes window topping, topping state switching, and multi window topping priority relationship
Useeffect, triggered when function components are mounted and unloaded
Share an example of running dash application in raspberry pie.
Kubernetes集群部署
栈的经典应用—括号匹配问题
605. Planting flowers
Determine the Photo Position
Codeforces Round #800 (Div. 2)AC
双向链表—全部操作
1605. Sum the feasible matrix for a given row and column
Oneforall installation and use
C language learning notes
计算时间差
1013. Divide the array into three parts equal to and
QT模拟鼠标事件,实现点击双击移动拖拽等
Codeforces Round #801 (Div. 2)A~C
Pull branch failed, fatal: 'origin/xxx' is not a commit and a branch 'xxx' cannot be created from it
Configuration du cadre flask loguru log Library
Discussion on QWidget code setting style sheet
Maximum product (greedy)