小y的容器(dp)

链接:登录—专业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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值