zoukankan      html  css  js  c++  java
  • topcoder srm 460 div1

    problem1 link

    设$f[i][j]$表示已经分配了answers中的前$i$个,分配给的问题的状态为 $j$的方案数。

    其中状态可以用$n$位的三进制表示,0表示还未分配,1表示已分配是 Yes,2表示已分配是No.

    problem2 link

    假设$n$个城市为[0,n-1]。设$f[i][j][t]$表示在[0,i]个城市中已经选择了$j$个城市,选择了$t$个人的概率。

    那么选择第$i+1$个城市的概率是$frac{k-j}{n-i-1}$.

    problem3 link

    首先,如果一个连通图中存在两个环,也就是有$n$个顶点,$n+1$条边,那么从其中一个环上的某一点(这一点不属于另外一个环)到另一个环上的某一点(同样这一点也不属于前一个环)会有超过两条简单路径。所以满足条件的连通图要么是树,要么是只有一个环(也就是树上多一条边)。

    假设给出的边使得$n$个顶点分成了$m$个连通分量,第$i$个连通分量中点的个数是$v_{i}$。

    (1)假设最后是一棵树(前提是$m$个连通分量中每个连通分量中都没有环)。最后的答案是$T(m)=n^{m-2}prod_{i=1}^{m}v_{i}$.这里要用到prufer编码。对于$m$个联通块的树,其prufer编码的长度为$m-2$。每个位置有$n$种情况,最后乘以叶子节点可以连出的边的数量。

    比如$m=3,n=4$,分别是1-2,3,4。那么长度为1的prufer编码可以是{1},{2},{3},{4}.(推导过程参看上面的链接)

    对于{1}来说,有两种:第一种: 1-3,1-4, 第二种1-3,2-4

    对于{2}来说,有两种:第一种: 2-3,2-4, 第二种2-3,1-4

    对于{3}来说,有两种:第一种: 3-1,3-4, 第二种3-2,3-4

    对于{4}来说,有两种:第一种: 4-1,4-3, 第二种4-2,4-3

    (2)有一个环。那么就要看这个环连通了$m$个联通块中的几个。

    第一种: 1个,那么只需要枚举是第几个联通块;

    第二种:2个,假设是联通块$a,b$.那么就是$C_{v_av_b}^{2}$

    第三种:大于等于3个,假设是$k$个,那么是$frac{(k-1)!}{2}prod_{i=1}^{k}v_{ci}^{2}$,其中$ci$第第$i$个选出的联通块的编号。这里除以2是因为有翻转导致重复的情况。比如$k=4$时,$abcd$和$dcab$是一样的。

    最后将连成的环看做一个连通分量,那么最后还有$m-k+1$个连通分量,将其连成一个树的方案为$T(m-k+1)$。

    code for problem1

    import java.util.*;
    import java.math.*;
    import static java.lang.Math.*;
    
    public class TheQuestionsAndAnswersDivOne {
    	
    	public int find(int n, String[] answers) {
    
    		int[] p = new int[n + 2];
    		p[0] = 1;
    		for (int i = 1; i < p.length; ++ i) {
    			p[i] = p[i - 1] * 3;
    		}
    
    		int[][] f = new int[answers.length][p[n]];
    		for (int i = 0; i < n; ++ i) {
    			int t = answers[0].equals("No")? 1 : 2;
    			f[0][t * p[i]] = 1;
    		}
    		for (int i = 1; i < answers.length; ++ i) {
    			int t = answers[i].equals("No")? 1 : 2;
    			for (int k = 0; k < p[n]; ++ k) {
    				if (f[i - 1][k] == 0) {
    					continue;
    				}
    				for (int j = 0; j < n; ++ j) {
    					int x = k / p[j] % 3;
    					if (x == 0 || x == t) {
    						int nk = k;
    						if (x == 0) {
    							nk += t * p[j];
    						}
    						f[i][nk] += f[i - 1][k];
    					}
    				}
    			}
    		}
    		int result = 0;
    		for (int i = 0; i < p[n]; ++ i) {
    			boolean tag = true;
    			for (int j = 0; j < n; ++ j) {
    				if (i / p[j] % 3 == 0) {
    					tag = false;
    					break;
    				}
    			}
    			if (tag) {
    				result += f[answers.length - 1][i];
    			}
    		}
    		return result;
    	}
    }
    

      

    code for problem2

    import java.util.*;
    import java.math.*;
    import static java.lang.Math.*;
    
    public class TheFansAndMeetingsDivOne {
    	
    	public double find(int[] minJ, int[] maxJ, int[] minB, int[] maxB, int k) {
    		final int n = minJ.length;
    		int s1 = 0, s2 = 0;
    		for (int i = 0; i < n; ++ i) {
    			s1 += maxJ[i];
    			s2 += maxB[i];
    		}
    		final int m = Math.min(s1, s2) + 1;
    		double[][][] f = new double[n][k + 1][m];
    		double[][][] g = new double[n][k + 1][m];
    
    
    		f[0][0][0] = 1 - 1.0 * k / n;
    		for (int i = minJ[0]; i <= maxJ[0] && i < m; ++ i) {
    			f[0][1][i] = 1.0 * k / n / (maxJ[0] - minJ[0] + 1);
    		}
    		g[0][0][0] = 1 - 1.0 * k / n;
    		for (int i = minB[0]; i <= maxB[0] && i < m; ++ i) {
    			g[0][1][i] = 1.0 * k / n / (maxB[0] - minB[0] + 1);
    		}
    
    		for (int i = 1; i < n; ++ i) {
    			for (int j = 0; j <= i && j <= k; ++ j) {
    				final double p = 1.0 * (k - j) / (n - i);
    				final double p1 = p / (maxJ[i] - minJ[i] + 1);
    				final double p2 = p / (maxB[i] - minB[i] + 1);
    				for (int t = 0; t < m; ++ t) {
    					f[i][j][t] += f[i - 1][j][t] * (1 - p);
    					g[i][j][t] += g[i - 1][j][t] * (1 - p);
    					if (j == k) {
    						continue;
    					}
    					for (int x = minJ[i]; x <= maxJ[i] && x + t < m; ++ x) {
    						f[i][j + 1][x + t] += f[i - 1][j][t] * p1;
    					}
    					for (int x = minB[i]; x <= maxB[i] && x + t < m; ++ x) {
    						g[i][j + 1][x + t] += g[i - 1][j][t] * p2;
    					}
    				}
    			}
    		}
    
    		double result = 0;
    		for (int i = 0; i < m; ++ i) {
    			result += f[n - 1][k][i] * g[n - 1][k][i];
    		}
    		return result;
    	}
    }
    

      


    code for problem3

    import java.util.*;
    import java.math.*;
    import static java.lang.Math.*;
    
    public class TheCitiesAndRoadsDivOne {
    
    	static final int MOD = 1234567891;
    
    	public int find(String[] map) {
    		final int n = map.length;
    		UnionSet unionSet = new UnionSet(n);
    		for (int i = 0; i < n; ++ i) {
    			for (int j = i + 1; j < n; ++ j) {
    				if (map[i].charAt(j) == 'Y') {
    					unionSet.merge(i, j);
    				}
    			}
    		}
    		List<Integer> list = new ArrayList<>();
    		int m = 0;
    		int circleNum = 0;
    		for (int i = 0; i < n; ++ i) {
    			if (unionSet.get(i) == i) {
    				++ m;
    				list.add(unionSet.vertexNum[i]);
    				circleNum += unionSet.edges[i] - unionSet.vertexNum[i] + 1;
    			}
    		}
    		if (circleNum > 1) {
    			return 0;
    		}
    
    		if (m == 1) {
    			if (circleNum == 1 || list.get(0) <= 2) {
    				return 1;
    			}
    			return list.get(0) * (list.get(0) - 1) / 2 - (list.get(0) - 1) + 1;
    		}
    
    		long[] p = new long[n + 1];
    		p[0] = 1;
    		for (int i = 1; i <= n; ++ i) {
    			p[i] = p[i-1] * n % MOD;
    		}
    		long result = p[m - 2];
    		for (int i = 0; i < m; ++ i) {
    			result = result * list.get(i) % MOD;
    		}
    		if (circleNum == 1) {
    			return (int)result;
    		}
    
    		int sum = 0;
    		for (int i = 0; i < m; ++ i) {
    			int t = list.get(i);
    			sum += t * (t - 1) / 2 - (t - 1);
    		}
    		result = result * (sum + 1) % MOD;
    
    		for (int i = 0; i < (1 << m); ++ i) {
    			int cnt = 0;
    			for (int j = 0; j < m; ++ j) {
    				if ((i & (1 << j)) != 0) {
    					++ cnt;
    				}
    			}
    			if (cnt < 2) {
    				continue;
    			}
    			long tmp = 1;
    			if (cnt == 2) {
    				for (int j = 0; j < m; ++ j) {
    					if ((i & (1 << j)) != 0) {
    						tmp *= list.get(j);
    					}
    				}
    				tmp = tmp * (tmp - 1) / 2;
    			}
    			else {
    				for (int j = 3; j <= cnt - 1; ++ j) {
    					tmp = tmp * j % MOD;
    				}
    				for (int j = 0; j < m; ++ j) {
    					if ((i & (1 << j)) != 0) {
    						tmp = tmp * list.get(j) * list.get(j) % MOD;
    					}
    				}
    			}
    			if (cnt == m) {
    				result = (result + tmp) % MOD;
    				continue;
    			}
    			tmp = tmp * p[(m - cnt + 1) - 2] % MOD;
    			long totVertex = 0;
    			for (int j = 0; j < m; ++ j) {
    				if ((i & (1 << j)) != 0) {
    					 totVertex += list.get(j);
    				}
    				else {
    					tmp = tmp * list.get(j) % MOD;
    				}
    			}
    			tmp = tmp * totVertex % MOD;
    			result = (result + tmp) % MOD;
    		}
    		return (int)result;
    	}
    
    	static class UnionSet {
    		int[] father = null;
    		int[] edges = null;
    		int[] vertexNum = null;
    
    		UnionSet(int n) {
    			father = new int[n];
    			edges = new int[n];
    			vertexNum = new int[n];
    			for (int i = 0; i < n; ++ i) {
    				father[i] = i;
    				edges[i] = 0;
    				vertexNum[i] = 1;
    			}
    		}
    
    		int get(int u) {
    			if (father[u] == u) {
    				return u;
    			}
    			return father[u] = get(father[u]);
    		}
    
    		void merge(int u, int v) {
    			int fu = get(u);
    			int fv = get(v);
    			++ edges[fu];
    			if (fu == fv) {
    				return;
    			}
    			father[fv] = fu;
    			vertexNum[fu] += vertexNum[fv];
    			edges[fu] += edges[fv];
    		}
    	}
    }
    

      

  • 相关阅读:
    人脸识别总结(附开源项目代码与各大数据集下载路径)
    simpledet 的配置
    论文笔记--PCN:Real-Time Rotation-Invariant Face Detection with Progressive Calibration Networks
    smallcorgi/Faster-RCNN_TF训练自己的数据
    保存文件名至txt文件中,不含后缀
    训练 smallcorgi/Faster-RCNN_TF 模型(附ImageNet model百度云下载地址)
    调试 smallcorgi/Faster-RCNN_TF 的demo过程遇到的问题
    python字符串前缀和格式化
    摩斯电码与字母相互转换
    django配置mysql
  • 原文地址:https://www.cnblogs.com/jianglangcaijin/p/7780855.html
Copyright © 2011-2022 走看看