灵魂滚烫, 命运冰凉|

fhq_treap

园龄:5年6个月粉丝:66关注:21

P1357 花园

算法

我们发现题目中m<5很小

所以我们可以使用二进制压缩。

我们用1来表示C0表示P,我们压缩的是当前这个状态的最后m位的状态 比如后m位是CCPP则压缩为(1100)2这个数

接下来我们讨论一下状态如何转移

首先好像我对于一个状态的转移和其他题解的方法不大相同。
我对于一个状态向其他状态的转移是这样的:

now_0 = (now << 1) & ((1 << m) - 1);
now_1 = (now << 1) & ((1 << m) - 1) + 1;

这个转移可能是更加符合题目的意思吧。
举个栗子:

就如题目中所给的例子 m=2 k=1

我们就有如下的转移:

00 >01

00 >00

10 >01

10 >00

01 >10

我们可以发现从现在这个状态[i,i+m][i+1,i+m+1]的状态转移相当把[i,i+m] 这个状态的第一个数字挤出去,再在最后一位填上新的数字,我们设f[i][j]为第i位向后m位状态为j的方案数。

那么我们就知道如果我们枚举[0,m]的状态 则我们的答案是f[n+1][j] j2进制下1的个数小于k。我们还发现每个f[i][j]都从f[i1][j]达到,所以我们可以用上滚动数组 这样能够做到70pts

但我们可是冲着100pts去的啊 区区70pts

我们可以预处理出这个一个矩阵,类似于邻接矩阵,将i>j这个一个关系,当成一条边存入,这个过程可以使用dfs。然后我们要做的是转移,就转换成了经典的图上求到达每个点的方案数了,类似于P2886 [USACO07NOV]Cow Relays G这个用矩阵快速幂的题目(建议先做这个题),我们本题也可以使用矩阵快速幂来进行加速。

最后上代码啦

#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
#define MOD 1000000007 

using namespace std;

ll n,m,k,fin = 0;

bool vis[(1 << 6) + 1][(1 << 6) + 1];

struct map{
	ll f[(1 << 6) + 1][(1 << 6) + 1]; 
	map(){
		memset(f,0,sizeof(f));
	}
}a,ans;

void dfs(ll now,ll last){
	if(vis[last][now])
	return;
	if(now >= (1 << m))
	return;
	vis[last][now] = 1;
	a.f[last][now] = 1;
	ll z = now;
	now = (now << 1) & ((1 << m) - 1);
	if(__builtin_popcount(now) >= k)
	dfs(now,z);
	else{
		dfs(now + 1,z);
		dfs(now,z);
	}
}

map operator * (const map &x,const map &y){
	map z;
	for(ll i = 0;i <= (1 << m) - 1;i ++)
	for(ll j = 0;j <= (1 << m) - 1;j ++)
	for(ll k = 0;k <= (1 << m) - 1;k ++)	
	z.f[i][j] = (z.f[i][j] + (1ll * x.f[i][k] * y.f[k][j]) % MOD) % MOD;
	return z;
} 
void quick(ll k){
	ans = a;
	k -= 1;
	while(k){
		if(k & 1) ans = ans * a;
		a = a * a;
		k >>= 1;
	}
}
int main(){
	scanf("%lld%lld%lld",&n,&m,&k);
    dfs(0,0);
    quick(n);
	for (int i = 0; i < (1 << m) - 1; ++i) {
		fin = (fin + ans.f[i][i]) % MOD;
	}
    cout<<fin;
} 

本文作者:fhq_treap

本文链接:https://www.cnblogs.com/dixiao/p/13849461.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   fhq_treap  阅读(110)  评论(0编辑  收藏  举报
编辑推荐:
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· .NET Core内存结构体系(Windows环境)底层原理浅谈
· C# 深度学习:对抗生成网络(GAN)训练头像生成模型
· .NET 适配 HarmonyOS 进展
阅读排行:
· DeepSeek+PageAssist实现本地大模型联网
· 手把手教你更优雅的享受 DeepSeek
· 腾讯元宝接入 DeepSeek R1 模型,支持深度思考 + 联网搜索,好用不卡机!
· 从 14 秒到 1 秒:MySQL DDL 性能优化实战
· AI工具推荐:领先的开源 AI 代码助手——Continue
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起