UVA - 11651 Krypton Number System

13 篇文章 0 订阅
10 篇文章 0 订阅

题目链接

寻找状态转移方程,dp[i][j]=\sum dp[i-tmp][k] ,tmp=(j-k)^{2}

题解参考处​​​​​​​

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
typedef unsigned long long ull;
const ull mod=(1ull<<32);
int N;
ull dp[40][40];
struct matrix{
	ull x[155][155];
};

matrix multi(matrix a,matrix b){
	matrix tmp;
	memset(tmp.x,0,sizeof(tmp.x));
	for(int i=1;i<=N;i++)
		for(int j=1;j<=N;j++)
			for(int k=1;k<=N;k++){
				tmp.x[i][j]=(tmp.x[i][j]+a.x[i][k]*b.x[k][j]%mod)%mod;
			}			
	return tmp;
}

matrix quick_multi(matrix a,int n){
	matrix tmp;
	for(int i=1;i<=N;i++)
		for(int j=1;j<=N;j++)
			tmp.x[i][j]=(i==j);
			
	while(n){
		if(n&1)
			tmp=multi(tmp,a);
		a=multi(a,a);
		n>>=1;
	}
	return tmp;
}

int main(){
	int T,b,s,t=0;
	
	scanf("%d",&T);
	while(T--){
		t++;
		scanf("%d%d",&b,&s);
		
		N=b*(b-1)*(b-1);
		memset(dp,0,sizeof(dp));
		int maxs=(b-1)*(b-1);
		for(int i=1;i<b;i++)
			dp[0][i]=1;
		for(int i=1;i<=maxs;i++){  //状态转移 
			for(int j=0;j<b;j++)
				for(int k=0;k<b;k++){ //在尾数为k的基础上加上一位j,尾数为j
					int tmp=(k-j)*(k-j);   //多出的分数为(k-j)*(k-j) 
					if(!tmp||tmp>i)	continue;
					dp[i][j]+=dp[i-tmp][k]%mod;
				}
		}
		
		ull sum=0;
		if(s<maxs){
			for(int i=0;i<b;i++)
				sum+=dp[s][i]%mod;
			printf("Case %d: %llu\n",t,sum);
			continue;
		}
		
		matrix st;
		memset(st.x,0,sizeof(st.x));
		for(int i=1;i<=N-b;i++)
			st.x[i][i+b]=1;
		for(int i=0;i<b;i++){
			for(int j=0;j<b;j++){
				if(i!=j){
					int mp=(i-j)*(i-j);
					st.x[N-b+i+1][(maxs-mp)*b+j+1]=1;
				}
			}
		}
		st=quick_multi(st,s-maxs+1);

		
		for(int i=N-b+1;i<=N;i++)
			for(int j=1;j<=N;j++)
				sum=(sum+dp[(j-1)/b][(j-1)%b]*st.x[i][j]%mod)%mod;  
		//sum+=(dp[(j-1)/b][(j-1)%b]*st.x[i][j]%mod)%mod;  这样答案就不一样了,T.T ,卡这里很久 

		printf("Case %d: %llu\n",t,sum);		
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值