hdu5103 RootedTree 状压dp,树形dp
来源:互联网 发布:加大usb电流软件 编辑:程序博客网 时间:2024/05/16 06:55
这题说的是给了n(14)个点,每个点都以他 为根的最大可容的孩子个数和最小的可溶孩子个数L[i] ,R[i]
问这n个点形成一棵树有多少种形态
我们让 dp[i][S] 表示 一 i为根节点 的 拥有孩子S(二进制数)状态的 方案数 , sub[S] , 表示 以 S 状态表示的 森林的 方案数, sum[S] 表示 一S 状态的 有根树 的 方案数
可以知道
dp[i][S] = sub[ S^(1<<i) ] { L[i]<=|S|<=R[i] }
sum[S] = dp[i][S] { i=0,1,2,3,,,n-1 | S&1<<i!=0 }
sub[S] = sub[S] + sum[H]*sub[S^H]{ H 为s 的 子集 ,然后 先固定 S 中第一个不是点 不是0 的一定要在 H 中, 这样是 为了保证 不会出现一个点被算了两次,可能这个点在枚举时存在对称性 , 我们一旦确定一个点在那个位置就可以避免这种情况的出现 }
#include<iostream>#include<cstring>#include<cstdio>#include<ostream>#include<istream>#include<algorithm>#include<queue>#include<string>#include<cmath>#include<set>#include<map>#include<stack>#include<vector>#define fi first#define se second#define pii pair<int,int>#define inf (1<<30)#define eps 1e-8#define ll long longusing namespace std;const int maxn=110005;const ll mod=1000000007;int n;int d[20][2];int num[1<<14];ll sum[1<<14];ll sub[1<<14];ll dp[1<<14][15];ll Dp(int s,int c);ll Sum(int s);ll Sub(int s){ if(s==0) return 1; if(sub[s]!=-1) return sub[s]; sub[s]=0; int id[15]; int cnt=0; for(int i=0;i<n;i++) { if(s&(1<<i)) { id[cnt++]=i; } } for(int i=1;i<(1<<cnt);i+=2) { int s1=0; for(int j=0;j<cnt;j++) { if(i&(1<<j)) { s1^=(1<<id[j]); } } sub[s]+=Sum(s1)*Sub(s^s1)%mod; sub[s]%=mod; } return sub[s];}ll Dp(int s,int c){ return Sub(s^(1<<c));}ll Sum(int s){ if(sum[s]!=-1) return sum[s]; sum[s]=0; for(int i=0;i<n;i++) { if(s&(1<<i)) { if(num[s]>=d[i][0]&&num[s]<=d[i][1]) sum[s]=(sum[s]+Dp(s,i))%mod; } } return sum[s];}void pre(){ memset(num,0,sizeof(num)); for(int i=0;i<(1<<14);i++) { int o=0; for(int j=0;j<14;j++) { if(i&(1<<j)) o++; } num[i]=o; }}int main(){ pre(); int t; scanf("%d",&t); while(t--) { scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d%d",&d[i][0],&d[i][1]); memset(sum,-1,sizeof(sum)); memset(sub,-1,sizeof(sub)); memset(dp,-1,sizeof(dp)); printf("%I64d\n",Sum((1<<n)-1)); } return 0;}
0 0
- hdu5103 RootedTree 状压dp,树形dp
- 树形dp
- 树形DP
- 树形dp
- 树形DP
- 树形dp
- 树形DP
- 树形DP
- 树形DP
- 树形DP
- 树形dp
- 树形dp
- 树形dp
- 树形dp
- 树形DP
- 树形DP
- 树形DP
- 树形DP
- 8.18总结
- 设置win7的MTU
- Swift-字典
- 搜索栏UISearchBar和UISearchController
- 【DirectX 2D游戏编程基础】DirectX精灵的创建
- hdu5103 RootedTree 状压dp,树形dp
- Codeforces Beta Round #1 A Theatre Square
- Swift-函数
- crontab学习笔记
- [c]sdnuoj1153 Grade School Multiplication
- CSU 1256 天朝的单行道
- 剑指offer 二进制中1的个数
- TCP/IP、Http、Socket的区别
- linux c编程 多线程(初级)