[abc] AtCoder Beginner Contest 244

前言

时间就是金钱 就是生命 ,所以直接从D题开始补了
传送门:

D.Swap Hats

题目很简单,但是有一个 分析状态 的思想值得学习

我们简单分为

  • (1)有三个不同
  • (2)有两个不同
  • (3)都相同

显然 状态(1)(3) 无论如何怎么操作都只能 转换到 状态(2)

但是状态(2) 一次操作 只能转换到 (1)(3)

因此在 1 e 18 1e^{18} 1e18偶数操作下,只有(1)(3)状态是合法的

Mycode

void solve()
{
	char a,b,c;cin>>a>>b>>c;
	char A,B,C;cin>>A>>B>>C;
	
	int t = (A == a) + (B == b) + (C  == c);
	if(!t || t== 3){
		cout<<"Yes"<<endl;
		return;
	}
	
	cout<<"No"<<endl;

}

E - King Bombee

一个 N ∗ M N*M NM的无向图

给你 S , T , K , X S,T,K,X S,T,K,X 询问有多少条长度为 K + 1 K+1 K+1 V s   t o   V t V_s \ to\ V_t Vs to Vt 路径满足 X X X出现了偶数次

我们设计状态为
f [ i ] [ j ] [ k ] f[i][j][k] f[i][j][k]表示前面有 i i i个字母,末尾是 j j j,并且出现 k k k X X X的状态

初始化 f [ 1 ] [ S ] [ 0 ] = 1 f[1][S][0] = 1 f[1][S][0]=1 最终状态 f [ k + 1 ] [ T ] [ 0 ] f[k+1][T][0] f[k+1][T][0]

因此我们只需要遍历 次数的时候 遍历一下所有边即可

在每次 f [ i − 1 ] [ j ] [ 1 ] ∣ ∣ f [ i − 1 ] [ j ] [ 0 ] f[i-1][j][1] ||f[i-1][j][0] f[i1][j][1]f[i1][j][0] 状态存在的时候做转移即可

Mycode

ll f[N][N][2];
vector<int> g[N];
int n,m,k,S,T,x;


void solve()
{
	cin>>n>>m>>k>>S>>T>>x;
	while(m -- ){	
		int a,b;cin>>a>>b;
		g[a].pb(b);g[b].pb(a);
	}
	
	f[1][S][0] = 1;
	
	//长度是  k+1
	for(int i=2;i<=k+1;i ++ ){
		for(int j = 1;j<=n;j++ ){
			if(f[i-1][j][0] || f[i-1][j][1]){
				for(auto e : g[j]){
					if(e == x){
							f[i][e][1] = (f[i][e][1] + f[i-1][j][0])%mod;
							f[i][e][0] = (f[i][e][0] + f[i-1][j][1])%mod;	
					}else{
							f[i][e][0] = (f[i][e][0] + f[i-1][j][0])%mod;
							f[i][e][1] = (f[i][e][1] + f[i-1][j][1])%mod;
						}
				}
			}
		}
	}
	cout<<f[k+1][T][0]<<endl;
	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值