首页 > 其他分享 >AT_ddcc2017_final_d なめらかな木 题解

AT_ddcc2017_final_d なめらかな木 题解

时间:2024-08-29 15:47:41浏览次数:9  
标签:rd ch 暴力 题解 ddcc2017 65 now final

首先考虑暴力 DP,设 \(f(i,v_1,v_2,now)\) 为已经将前 \(i\) 个数填入,\(i\) 填在 \(v_1\),\(j\) 填在 \(v_2\) 点,已经填完点的状态是 \(now\)(状压一下存在一个 long long 里)的方案数。转移时直接枚举下一个点暴力转移,只需要保证新的点没有被访问过,并且填上新点后,\(v_1\) 的所有邻接点都被填上即可。

其实直接暴力转移,复杂度是对的。

我们考虑对于一个状态 \((i,v_1,v_2,now)\),将 \(v_1\) 和 \(v_2\) 在树中剪掉,剩下的连通块(最多 \(7\) 个,因为每个点度数最多为 \(4\))中,要么全被填了,要么都没被填。因为一个连通块内被填的点上的数一定小于等于 \(n-2\),后面填的点一定和这些点的差一定大于 \(2\),因此一定不合法。

状态数最多为 \(n^3 \times 2^7\),复杂度 \(O(n^3 \times 2^7)\)。

注意特判 \(n=1\) 的情况。

代码

点击查看代码
#include<bits/stdc++.h>
using namespace std;
inline void rd(){}
template<typename T,typename ...U>
inline void rd(T &x,U &...args){
	char ch=getchar();
	T f=1;x=0;
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
	x*=f;rd(args...);
}
const int mod=1e9+7;
unordered_map<long long,int> mp[65][65][65];
vector<int> e[65];int n;
signed main(){
	rd(n);
	if(n==1){
		printf("1\n");
		return 0;
	}
	for(int i=1;i<n;i++){
		int x,y;rd(x,y);
		e[x].push_back(y);
		e[y].push_back(x);
	}
	for(int v1=1;v1<=n;v1++)
		for(int v2=1;v2<=n;v2++){
			if(v1==v2)continue;
			mp[2][v1][v2][(1ll<<v2)|(1ll<<v1)]+=1;
		}
	for(int i=2;i<n;i++){
		for(int v1=1;v1<=n;v1++){
			for(int v2=1;v2<=n;v2++){
				if(v1==v2)continue;
				long long bas=0;
				for(int x:e[v1])bas|=(1ll<<x);
				for(int x=1;x<=n;x++){
					for(pair<long long,int> p:mp[i][v1][v2]){
						if(p.first&(1ll<<x))continue;
						if(((p.first|(1ll<<x))&bas)==bas){
							(mp[i+1][v2][x][p.first|(1ll<<x)]+=mp[i][v1][v2][p.first])%=mod;
						}
					}
				}
			}
		}
	}
	int ans=0;
	for(int v1=1;v1<=n;v1++)
		for(int v2=1;v2<=n;v2++){
			if(v1==v2)continue;
			for(auto p:mp[n-1][v1][v2])
				(ans+=p.second)%=mod;
		}
	printf("%d\n",ans);
	return 0;
}

标签:rd,ch,暴力,题解,ddcc2017,65,now,final
From: https://www.cnblogs.com/11-twentythree/p/18386848

相关文章

  • Luogu P4425 转盘 题解 [ 黑 ] [ 线段树 ] [ 贪心 ] [ 递归 ]
    转盘:蒟蒻的第一道黑,这题是贪心和线段树递归合并的综合题。贪心破环成链的trick自然不用多说。首先观察题目,很容易发现一个性质:只走一圈的方案一定最优。这个很容易证,因为再绕一圈回来标记前面的和等前面的标记完之后继续走是等价的,并且再绕一圈甚至可能更劣。于是,我们只用走......
  • 题解:P9938 [USACO21OPEN] Acowdemia II B
    前言:原来的tj干了一堆什么建图啊之类的,但其实不要这么复杂。注:下文中\(n\)是各成员名字列表。从\(K=1\)开整。如果情况是\(n_i<n_{i+1}<\cdots<n_j\),那么显然,咱就不知道关于成员\(n_i,\cdots,n_j\)的相对资历的信息。也许所有这帮成员都做出了相同的贡献。......
  • AWTF2024A Moving Slimes 题解
    发现史莱姆不合并也不会影响答案,所以就不用考虑合并了。这样处理之后,史莱姆的移动可以看作是受到与其不在同一位置的史莱姆的吸引所完成的,每只史莱姆可以给其他史莱姆一个单位的吸引力。因为每只史莱姆提供的吸引力是恒定的,所以考虑把吸引力放在它们的重心上,设\(pre_i\)表示坐......
  • PHP8面向对象快速入门三 类的继承 类方法属性重写和final关键字 parent调用父类的方法
    在PHP中,类的继承(继承)是一种机制,允许一个类继承另一个类的属性和方法,从而实现代码的重用和扩展。继承可以帮助你创建一个基于现有类的新类,保留原有类的特性并增加或修改其功能。classAnimal{public$name='dongwu';protected$age=1;private......
  • 历年CSP-J初赛真题解析 | 2016年CSP-J初赛阅读程序(23-26)
    学习C++从娃娃抓起!记录下CSP-J备考学习过程中的题目,记录每一个瞬间。附上汇总贴:历年CSP-J初赛真题解析|汇总_热爱编程的通信人的博客-CSDN博客#include<iostream>usingnamespacestd;intmain(){intmax,min,sum,count=0;inttmp;cin>>tmp;......
  • CF1286E Fedya the Potter Strikes Back 题解
    题目链接点击打开链接题目解法牛题!题目实际上是要每次加入一个字符,求所有的\(border\)的神秘度之和考虑从前\(i-1\)个字符到前\(i\)个字符\(border\)的变化如果\(str_1=str_i\),会加入长度为\(1\)的\(border\),这一部分可以暴力加且只会保留\(i-1\)的\(border......
  • AT cf17 final J Tree MST
    ATcf17finalJTreeMST考场上想出的黑题,然而写挂了……思路考场推出boruvka算法,会的直接跳过就好。结论:一个点向另外一个点连出的最小边,一定在最小生成树上。证明:参考Kruskal生成树的流程,若当前边(最小边)不在最小生成树上,表明边的两端已经在同一个连通块中。那么存在一......
  • 华为java岗经典面试题解析
    题目为在一个整形的数组中,在数组中只有一值个是不重复的,其他的值都是有两个重复的值,找出不重复的那个值。{11,11,12,13,13,16,16}解析为当用Java来解决这个问题时,可以使用异或运算来找出只出现一次的元素。以下是一个示例Java程序,演示了如何在一个整型数组中找出只出现一次的元......
  • 洛谷P5322 [BJOI2019] 排兵布阵 题解
    代码#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongintdp[20001],a[101][101],s,n,m;signedmain(){ cin>>s>>n>>m; for(intj=1;j<=s;j++){ for(inti=1;i<=n;i++){ cin>>a[i][j]; } } for(inti=1;......
  • Java中final关键字的学习
    final关键字目录final关键字1.修饰变量2.修饰方法3.修饰类4.修饰方法参数注意事项示例在Java编程语言中,final关键字是一个非常重要的概念,它用于表示一个变量、方法或类是不可变的或不能被进一步修改的。以下是final关键字的几种常见用法:1.修饰变量常量:final修饰的变量......