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

    problem1 link

    以两个点$p,q$为中心的两个正方形的边长和最大为$2dist(p,q)$,即$p,q$距离的两倍。

    也就是两个$p,q$的连线垂直穿过两个正方形的一对边且平分两个正方形。

    problem2 link

    简化一下题意就是每个base和每个plant都有一个代价。要么付出某个base的代价,要么付出其对应的plant的代价。

    将base和plant建立网络流。

    源点到每个plant的边的流量为其代价

    base到汇点的边的流量为其代价

    base与其对应plant的边的流量为无穷大。

    然后求最小割即可。

    割到的plant就说明要付出这个plant的代价,割到的base就说明付出这个base的代价。

    problem3 link

    令$p=frac{1}{d},q=frac{d-1}{d}$

    在$[n-d,n-1]$中任意一个格子,其一步到达$n$的概率都是$p$。恰好经过$t$步到达$n$的概率为$pq^{t-1}$

    设$p1[i]$表示先手恰好经过$i$步第一次进入$[n-d,n-1]$区间的概率;

    设$p2[i]$表示后手恰好经过$i$步第一次进入$[n-d,n-1]$区间的概率;

    设$g(i,j)$表示先手、后手分别经过$i,j$步到达$[n-d,n-1]$区间且先手胜利的概率。

    $g(i,j)$的计算方法为:

    ===============================

    g(i,j)=0

    if(i<j) { 

    $g(i,j) += p1[i]*p2[j]*(1-q^{j-i})$  //在后手未进入最后区间时取得胜利

    }

    $g(i,j)+=p1[i]*p2[j] * q^{|i-j|} * frac{d}{d+d-1}$  //都进入最后区间再经过若干轮角逐后取得胜利

    ===============================

    那么答案为所有的$g(i,j)$之和。

    code for problem1

    import java.util.*;
    import java.math.*;
    import static java.lang.Math.*;
    
    public class TurretPlacement {
    	
    	public long count(int[] x, int[] y) {
    		long result = 0;
    		for (int i = 0; i < x.length; ++ i) {
    			for (int j = i + 1; j < x.length; ++ j) {
    				result += cal(x[i], y[i], x[j], y[j]);
    			}
    		}
    		return result;
    	}
    	long cal(int x1, int y1, int x2, int y2) {
    		long d = (long)(Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)) * 2);
    		return d * (d - 1) / 2;
    	}
    }
    

      

    code for problem2

    import java.util.*;
    import java.math.*;
    import static java.lang.Math.*;
    
    
    class MaxFlow {
    	static class node
    	{
    		int v,cap,next;
    	};
    
    	List<node> edges = null;
    	int[] head = null;
    	int vertexNum;
    	int[] pre = null;
    	int[] cur = null;
    	int[] num = null;
    	int[] h = null;
    
    	public MaxFlow(int vertexNum) {
    		this.vertexNum = vertexNum;
    		edges = new ArrayList<>();
    		head = new int[vertexNum];
    		Arrays.fill(head, -1);
    		pre = new int[vertexNum];
    		cur = new int[vertexNum];
    		num = new int[vertexNum];
    		h = new int[vertexNum];
    	}
    
    
    	private void addEdge(int u, int v, int cap)
    	{
    		node p = new node();
    		p.v = v;
    		p.cap = cap;
    		p.next = head[u];
    		head[u] = edges.size();
    		edges.add(p);
    	}
    
    	public void add(int u, int v, int cap)
    	{
    		addEdge(u, v, cap);
    		addEdge(v, u,0);
    	}
    
    
    
    	public int getMaxflow(int source, int sink)
    	{
    		for (int i = 0; i < vertexNum; ++ i) {
    			cur[i] = head[i];
    			num[i] = 0;
    			h[i] = 0;
    		}
    		int u = source;
    		int result = 0;
    		while (h[u] < vertexNum)
    		{
    			if (u == sink)
    			{
    				int Min=Integer.MAX_VALUE;
    				int v = -1;
    				for (int i = source; i != sink; i = edges.get(cur[i]).v)
    				{
    					int k=cur[i];
    					if(edges.get(k).cap < Min) {
    						Min = edges.get(k).cap;
    						v = i;
    					}
    				}
    				result += Min;
    				u=v;
    				for (int i = source; i != sink; i = edges.get(cur[i]).v)
    				{
    					int k=cur[i];
    					edges.get(k).cap -= Min;
    					edges.get(k ^ 1).cap += Min;
    				}
    			}
    			int index = -1;
    			for (int i = cur[u]; i != -1; i = edges.get(i).next)
    			{
    				if (edges.get(i).cap > 0 && h[u] == h[edges.get(i).v] + 1) {
    					index = i;
    					break;
    				}
    			}
    			if (index != -1)
    			{
    				cur[u] = index;
    				pre[edges.get(index).v]=u;
    				u=edges.get(index).v;
    			}
    			else
    			{
    				if (--num[h[u]] == 0) {
    					break;
    				}
    				int k = vertexNum;
    				cur[u] = head[u];
    				for (int i = head[u]; i != -1; i = edges.get(i).next)
    				{
    					if(edges.get(i).cap>0 && h[edges.get(i).v] < k)
    					{
    						k = h[edges.get(i).v];
    					}
    				}
    				if (k + 1 < vertexNum) {
    					num[k + 1] += 1;
    				}
    				h[u] = k + 1;
    				if (u != source) u=pre[u];
    			}
    		}
    		return result;
    	}
    }
    
    public class GreenWarfare {
    
    	int p2(int x) {
    		return x * x;
    	}
    
    	public int minimumEnergyCost(int[] canonX, int[] canonY, int[] baseX, int[] baseY,
    															 int[] plantX, int[] plantY, int energySupplyRadius) {
    		final int n = baseX.length;
    		final int m = plantX.length;
    		MaxFlow maxFlow = new MaxFlow(n + m + 2);
    		for (int j = 0; j < m; ++ j) {
    			int c = Integer.MAX_VALUE;
    			for (int i = 0; i < canonX.length; ++ i) {
    				c = Math.min(c, p2(canonX[i] - plantX[j]) + p2(canonY[i] - plantY[j]));
    			}
    			maxFlow.add(0, j + 1, c);
    		}
    		for (int j = 0; j < n; ++ j) {
    			int c = Integer.MAX_VALUE;
    			for (int i = 0; i < canonX.length; ++ i) {
    				c = Math.min(c, p2(canonX[i] - baseX[j]) + p2(canonY[i] - baseY[j]));
    			}
    			maxFlow.add(m + j + 1, m + n + 1, c);
    		}
    		for (int i = 0; i < m; ++ i) {
    			for (int j = 0; j < n; ++ j) {
    				int d = p2(baseX[j] - plantX[i]) + p2(baseY[j] - plantY[i]);
    				if ( d <= p2(energySupplyRadius)) {
    					maxFlow.add(i + 1, m + j + 1, Integer.MAX_VALUE);
    				}
    			}
    		}
    		return maxFlow.getMaxflow(0, m + n + 1);
    	}
    }
    

      

    code for problem3

    import java.util.*;
    import java.math.*;
    import static java.lang.Math.*;
    
    public class BouncingDiceGame {
    	
    	public double winProbability(int n, int d, int x, int y) {
    		double[] p1 = cal(n, d, x);
    		double[] p2 = cal(n, d, y);
    		double[] p = new double[n];
    		p[0] = 1;
    		p[1] = (d - 1.0) / d;
    		for (int i = 2; i < n; ++ i) {
    			p[i] = p[i - 1] * p[1];
    		}
    		double result = 0;
    		for (int i = 0; i < p1.length; ++ i) {
    			for (int j = 0; j < p2.length; ++ j) {
    				if (i < j) {
    					result += p1[i] * p2[j] * (1 - p[j - i]);
    				}
    				result += p1[i] * p2[j] * p[Math.abs(i - j)] * d / (d + d - 1);
    			}
    		}
    		return result;
    	}
    	double[] cal(int n, int d, int x) {
    		if (x >= n - d) {
    			double[] result = new double[1];
    			result[0] = 1;
    			return result;
    		}
    		final int m = n - d - x;
    		double[] result = new double[m + 1];
    		result[0] = 0;
    		double[][] f = new double[2][n];
    		for (int i = x; i <n; ++ i) {
    			f[0][i] = 1;
    		}
    		int pre = 0;
    		int cur = 1;
    		for (int i = 1; i <= m; ++ i) {
    			Arrays.fill(f[cur], 0);
    			for (int j = x + 1; j < n; ++ j) {
    				int rr = j - 1 >= n - d? n - d - 1 : j - 1;
    				int ll = j - d - 1 >= 0? j - d - 1: 0;
    				if (rr < ll) {
    					continue;
    				}
    				f[cur][j] = (f[pre][rr] - f[pre][ll] ) / d;
    			}
    			for (int j = x; j < n; ++ j) {
    				f[cur][j] += f[cur][j - 1];
    			}
    			result[i] = f[cur][n - 1] - f[cur][n - d - 1];
    			pre ^= 1;
    			cur ^= 1;
    		}
    		return result;
    	}
    }
    

      

  • 相关阅读:
    输入年月日,输出这一天是这一年的多少天
    判断体重是否标准 男标准=身高-100±3 女标准=身高-110±3
    if 条件运算符
    24小时换算成12小时&&判断正负数
    运算符(编程)
    定义变量
    基础知识
    java线程阻塞中断与LockSupport使用介绍(转)
    01背包问题--动态规划解法(2)(转载)
    01背包问题--动态规划解法
  • 原文地址:https://www.cnblogs.com/jianglangcaijin/p/7784017.html
Copyright © 2011-2022 走看看