ac1412. 邮政货车(插头DP)

题目

原题链接:点击这里
大致题意:求解n*4的方格中,哈密顿回路的数量

思路

表示的方法还是跟插头dp的左右表示法一样,这边(打表)
在这里插入图片描述

注意起始状态和终止状态的合法性
在这里插入图片描述

代码实现

因为这题里面嵌套了高精度,所以建议先打低精度的正解,再打高精度

#include<bits/stdc++.h>
#include<unordered_map>
#include<unordered_set>
using namespace std;
#define el '\n'
#define cl putchar('\n')
#define pb push_back
#define fir first
#define sec second

typedef long long ll;
typedef pair<int,int> pii;
typedef vector<int> vci;
typedef map<int,int> mii;
typedef mii::iterator mii_it;
typedef mii::reverse_iterator mii_rit;

const int N=1e3+10,M=1e3+10;
//这种里面套高精度的题目,建议先写完低精度再写高精度 
int T,n,m,x,y,k;
int w[6][6]={
	{1,0,1,1,0,0},{0,1,0,0,1,0},{0,1,0,0,1,0},{0,1,0,0,1,0},{1,0,1,1,0,1},{0,0,0,0,1,0}
}; 
int f[N][6][M];//设有1000位 
void add(int a[],int b[]){
	for(int i=0,t=0;i<M;i++){
		t+=a[i]+b[i];
		a[i]=t%10;
		t/=10;
	}
}
int main() {//求解哈密顿回路的条数 
	cin.tie(0);
	cout.tie(0);
	cin>>n;
	f[1][1][0]=f[1][4][0]=1;//初始状态只有这两种状态合法 
	for(int i=2;i<n;i++){
		for(int j=0;j<6;j++){
			for(int k=0;k<6;k++){
				if(w[k][j])add(f[i][j],f[i-1][k]);//因为w[k][j]就只有0和1两种状态 
			}
		}                      
	}
	int res[M]={0};
	add(res,f[n-1][0]),add(res,f[n-1][4]);//末尾状态就这两种合法方案 
	add(res,res);//等价与res*2,顺时针+逆时针 
	k=M-1;
	while(k>0&&!res[k])k--;//去除前导零 
	for(int i=k;i>=0;i--)cout<<res[i];
	cl;
	//以下为低精度写法 
//	f[1][1]=f[1][4]=1;
//	for(int i=2;i<n;i++){
//		for(int j=0;j<6;j++){
//			for(int k=0;k<6;k++){
//				f[i][j]+=f[i-1][k]*w[k][j];
//			}
//		}                      
//	}
//	int res=0;
//	res=f[n-1][0]+f[n-1][4];
//	cout<<res*2; 
}




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值