CodeChef January Long Challenge 2016 - SEAKAM

来源:互联网 发布:贵州省大数据局电话 编辑:程序博客网 时间:2024/06/16 09:11
  • 又是这种类型的DP,看似需要 n! 的复杂度,其实定义好dp状态就行啦!

题意:

给定一个包含 N 个点的无向图,给定 k 条边,表示无向图中这些边不存在,其余不包括在这 k 条边中的边都存在,求走完整个图(每个点只能访问一次)有多少种走法?
范围:
1N1050k7

思路:

转化一下,问题就是求有多少种 1n 排列使得排列中不会出现那 k 对数在排列中相邻。

因为 k 比较小,而且这些特殊点最多也只有 14 个,所以我们可以去数位 dp 枚举这14个点的排列状态,然后去加入剩余没有用过的特殊点,如果相邻的两个特殊点属于上面 k 对中的一对的话,那么就这两个点之间必须至少加入一个点,考虑 dp 状态 dp[i][j][k] 表示 i 状态下,最后一个被排列的点为 j ,用掉了 k 个非特殊点的排列方式!

转移就很简单了啊!略。。。。

代码:

let k = faulty_nodes.size()let ans = 0 //counter variablelet normal_nodes = N - k;for mask = 1 to (2^k-1){    for first_node = 0 to k-1    {        for number_tied = 0 to k-1        {            //appending a new node to the beginning of the arrangement that            //is given by mask.            for new_first = 0 to k-1            {                if(new_first bit in mask == 0)                {                    new_mask = bitwise_or(mask, 2^new_first)                    missing_edge = 1 if edge (new_first, first_node) missing else 0                    //adding to the count of sequences starting with new_first and                    //containing faulty nodes as the ones in the new_mask                    dp[new_mask][new_first][number_tied + missing_edge] += dp[mask][first_node][number_tied];                    //note that if the edge (new_first, first_node) is missing,                    //we will have to tie an element to first_node, i.e.,                    //increasing number_tied by 1.                }            }            if(mask == (2^k - 1))            {                //if all the faulty nodes have been arranged then we can                //count the number of valid permutations for this                //particular arrangement                total_objects = N - number_tied;                val = dp[mask][first_node][number_tied];                //getting all ways of arranging items                get_ways = (total_objects choose k) * (val);                //multiplying the number of ways of permuting normal nodes.                get_ways = (get_ways * factorial[normal_nodes]);                //adding to the counter variable                ans = (ans + get_ways);            }        }    }}
0 0