• 【状态压缩DP】CF D. A Simple Task


    【状态压缩DP】CF D. A Simple Task求环的个数

    题目链接
    image

    铺垫

    二进制的一些操作

    寻找第一个1 lowbit

    lowbit是树状数组中的老熟人了,原理是运用了原码和补码的特性。

    int inline lowbit(int x)
    {
        return x&(-x)
    }
    

    合并状态 利用|运算

    sta1|sta2
    

    查找第k位上的数字是1,还是0

    (s>>k)&1
    

    思路

    我们可以用一串01数字,来表示各个位置的占用情况。

    比如101001,(1表示灯亮,0表示灯灭),故而在这里,我们可以知道1、3、6号灯处于亮的状态,2、4、5号灯处于灭的状态。

    因而,我们可以定义一个二维dp数组d[i][j],数字i用来表示当前连线的点,j代表当前连线的终点,d[i][j]表示拥有状态i表示的点的集合且以点j为结尾的连线的个数。

    同时为了避免重复,我们对起点进行枚举。

    举个例子,我们可以对加入公司的员工按ta们的起始工资进行分类,这样的分类方式,必然不会出现重复。

    (在代码实现中,若新加入的点小于起点的编号,那么就不考虑该点的加入)

    • 其他
    • ABC(A)和ACB(A)这两个环本质上是一样的
    • ABA不符合题目标准,且在dp过程中有且仅有会产生m个
    • 因而,需要对答案进行修正,(ans-m)/2.
    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int N = 20 ;
    ll d[1<<N][N],g[N][N],n;
    ll maxn,m,q;
    int inline lowbit(int x)
    {
    	return x&(-x);
    }
    void init()
    {
    	cin>>n;
    	maxn = (1<<n)-1;
    	cin>>m;
    	for(int i=1;i<=m;i++)
    	{
    		int a,b;
    		cin>>a>>b;
    		a--;b--;
    		g[a][b] = g[b][a] = 1;
    	}
    	for(int i=0;i<n;i++)
    	    d[1<<i][i] = 1;
    }
    ll dp()
    {
        ll ans = 0;
    	for(int i=0;i<=maxn;i++)//状态从小到大进行枚举,也保证了正常的顺序 
    	{
    		int t = lowbit(i);
    		for(int j=0;j<n;j++) //枚举状态i的结尾顶点 
    		    if(!d[i][j] || (1<<j)<t) continue;//不存在和小于起点,直接跳过 
    		    else for(int k=0;k<n;k++) //尝试去接上新的点
    			{
    			    if(!g[j][k]||(1<<k)<t) continue;//如果不导通或者小于起点,直接跳过。
    				if( (i>>k)&1 )
    				{
    			        if( t == (1<<k) )
    					   ans += d[i][j];		
    				}	
    				else
    					d[ (1<<k)|i ][k] += d[i][j];
    			} 
    	}
    	ans = (ans-m)/2;
    	return ans;
    }
    int main()
    {
    	ios::sync_with_stdio(false);
    	cin.tie(0);
    	cout.tie(0);
    	init();
    	cout<<dp(); 
    	return 0;
    }
    
  • 相关阅读:
    python 如何把在字符串里面的名字变成变量,进行复制
    2017-05-30 英语
    RYU 中如钩构建TCP数据包,设置ACK等标志
    Arch linux LXR 安装过程
    ubuntu如何配置lxr
    2017-05-27 英语
    Emacs学习笔记:移动
    9.特殊矩阵的压缩存储
    13.链路层设备
    9.CSMA_CD协议
  • 原文地址:https://www.cnblogs.com/BeautifulWater/p/15806846.html
Copyright © 2020-2023  润新知