zoukankan      html  css  js  c++  java
  • HDU 4921 Map(状态压缩)

    题意看这篇博客

    思路参考的这篇博客

    补充:面对这种问题有一个常见的套路。比如计算若干个区间对答案的贡献这种问题,直接暴力可能复杂度到O(n ^ 2), 而我们可以计算出每个元素在多少个合法区间中,然后计算贡献,这样可以降到O(n)。对于此题,计算第一类贡献时就是这种方法。计算有多少种情况包含了这个元素,这样就算出了这种元素对第一种答案的贡献。有一个坑点需要注意,在读入每条边x, y时,必选立刻标记y已经访问过,这样最后没被标记过的就是链头。如果不提前标记,从前往后扫描时第一次遇到的没标记的点不一定是链头。

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 10010;
    int tot;
    int Next[maxn], now[15], len[15];
    bool v[maxn];
    int val[maxn];
    int main() {
    	int T, x, y, n, m;
    	scanf("%d", &T);
    	double res, ans, sum, method;
    	bool flag;
    	int num;
    	while(T--) {
    		scanf("%d%d", &n, &m);
    		memset(v, 0, sizeof(v));
    		memset(Next, 0, sizeof(Next));
    		memset(len, 0, sizeof(len));
    		memset(now, 0, sizeof(now));
    		tot = 0;
    		res = 1;
    		ans = 0;
    		for (int i = 1; i <= n; i++) {
    			scanf("%d", &val[i]);
    		}
    		for (int i = 1; i <= m; i++) {
    			scanf("%d%d", &x, &y);
    			x++, y++;
    			Next[x] = y;
    			v[y] = 1;
    		}
    		for (int i = 1; i <= n; i++) {
    			if(v[i]) continue;
    			now[tot] = i;
    			for (int j = i; j; j = Next[j]) {
    				len[tot]++;
    			}
    			res *= len[tot] + 1;
    			tot++;
    		}
    		for (int dep = 1;; dep++) {
    			int cnt = 0;
    			for (int i = 0; i < tot; i++) {
    				if(now[i])
    					cnt++;
    			}
    			if(cnt == 0) break;
    			for (int i = 1; i < (1 << tot); i++) {
    				num = 0;
    				sum = 0, method = 1; 
    				flag = 0;
    				for (int j = 0; j < tot; j++) {
    					if((i >> j) & 1) {
    						if(!now[j]) {
    							flag = 1;
    							break;
    						}
    						num++;
    						sum += val[now[j]];
    						method *= (len[j] - dep + 1);
    					} else {
    						method *= min(dep, len[j] + 1);
    					}
    				}
    				if(!flag) {
    					ans += method * sum;
    					if(num > 1)
    						ans += method * sum * num / cnt;
    				}
    			}
    			for (int i = 0; i < tot; i++)
    				now[i] = Next[now[i]];
    		}
    		printf("%.3f
    ", ans / (res - 1));
    	}
    } 
    

      

  • 相关阅读:
    python中的split、rsplit、splitlines
    docker 启动,端口映射,挂载本地目录
    pycharm18.2.4 + Python3.7.1 安装salt报错python pip install salt: Command "python setup.py egg_info" failed with error code 10 及解决方法
    Dockerfile 下安装Python3.7.4 环境命令
    linux项目部署学习(5)
    linux环境下安装selenium(python3)
    linux项目部署学习(4)
    linux项目部署学习(3) -nginx/发布crm
    linux项目部署学习(2)
    nginx语法之location详解
  • 原文地址:https://www.cnblogs.com/pkgunboat/p/10553619.html
Copyright © 2011-2022 走看看