链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
思路:
容器只有三个,差也只有三个,可以考虑直接开到状态里面
#include<bits/stdc++.h>
#define lowbit(x) ((x)&(-x))
#define int long long
using u64 = unsigned long long;
using namespace std;
std::mt19937_64 rng;
const int N=2e4+10,mod=1e9+7;
int m,n,no[N][4],dp[N][5][5][5];
void add(int &x,int y) {x=(x+y)%mod;}
int f(int x)
{
if(x==4||x==3) return x;/*坑:x==3时并不能放他加到4,4表示容器为空的情况意义不同*/
return x+1;
}
signed main()
{
int i,j,x,y,z;
scanf("%lld%lld",&n,&m);
for(i=1; i<=m; i++)
{
scanf("%lld %lld",&x,&y);
no[x][y]=1;
}
memset(dp,0,sizeof(dp));/*(放完i后,三个容器中最大值跟i差值分别为x,y,z的状态)*/
dp[0][4][4][4]=1;
for(i=1; i<=n; i++)
for(x=0; x<=4; x++)
for(y=0; y<=4; y++)
for(z=0; z<=4; z++)/*枚举i-1的所有情况,让x放1,2 ,3这三种操作分别更新这个状态*/
{
if(!no[i][1]&&(x==4||x+1<=3)) add(dp[i][0][f(y)][f(z)],dp[i-1][x][y][z]);
if(!no[i][2]&&(y==4||y+1<=3)) add(dp[i][f(x)][0][f(z)],dp[i-1][x][y][z]);
if(!no[i][3]&&(z==4||z+1<=3)) add(dp[i][f(x)][f(y)][0],dp[i-1][x][y][z]);
}
int ans=0;
for(x=0; x<=3; x++)
for(y=0; y<=3; y++)
for(z=0; z<=3; z++)
{
add(ans,dp[n][x][y][z]);
}
printf("%lld",ans);
return 0;
}