【Manthan, Codefest 16E】【DP 从右向左线性扫描不用ST-RMQ】Startup Funding 最大的min(取min,取max) + n值选k最小做权的期望

E. Startup Funding
time limit per test
3 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

An e-commerce startup pitches to the investors to get funding. They have been functional for n weeks now and also have a website!

For each week they know the number of unique visitors during this week vi and the revenue ci. To evaluate the potential of the startup at some range of weeks from l to r inclusive investors use the minimum among the maximum number of visitors multiplied by 100 and the minimum revenue during this period, that is:

The truth is that investors have no idea how to efficiently evaluate the startup, so they are going to pick some k random distinct weeks liand give them to managers of the startup. For each li they should pick some ri ≥ li and report maximum number of visitors and minimum revenue during this period.

Then, investors will calculate the potential of the startup for each of these ranges and take minimum value of p(li, ri) as the total evaluation grade of the startup. Assuming that managers of the startup always report the optimal values of ri for some particular li, i.e., the value such that the resulting grade of the startup is maximized, what is the expected resulting grade of the startup?

Input

The first line of the input contains two integers n and k (1 ≤ k ≤ n ≤ 1 000 000).

The second line contains n integers vi (1 ≤ vi ≤ 107) — the number of unique visitors during each week.

The third line contains n integers ci (1 ≤ ci ≤ 107) —the revenue for each week.

Output

Print a single real value — the expected grade of the startup. Your answer will be considered correct if its absolute or relative error does not exceed 10 - 6.

Namely: let's assume that your answer is a, and the answer of the jury is b. The checker program will consider your answer correct, if .

Examples
input
3 2
3 2 1
300 200 300
output
133.3333333
Note

Consider the first sample.

If the investors ask for li = 1 onwards, startup will choose ri = 1, such that max number of visitors is 3 and minimum revenue is 300. Thus, potential in this case is min(3·100, 300) = 300.

If the investors ask for li = 2 onwards, startup will choose ri = 3, such that max number of visitors is 2 and minimum revenue is 200. Thus, potential in this case is min(2·100, 200) = 200.

If the investors ask for li = 3 onwards, startup will choose ri = 3, such that max number of visitors is 1 and minimum revenue is 300. Thus, potential in this case is min(1·100, 300) = 100.

We have to choose a set of size 2 equi-probably and take minimum of each. The possible sets here are :{200, 300},{100, 300},{100, 200}, effectively the set of possible values as perceived by investors equi-probably: {200, 100, 100}. Thus, the expected value is (100 + 200 + 100) / 3 = 133.(3).



#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b>a)a = b; }
template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b<a)a = b; }
const int N = 1e6+10, M = 0, Z = 1e9 + 7, ms63 = 0x3f3f3f3f;
int n, k;
int a[N], b[N], c[N];
int main()
{
	while (~scanf("%d%d", &n,&k))
	{
		for (int i = 1; i <= n; ++i)scanf("%d", &a[i]), a[i] *= 100;
		for (int i = 1; i <= n; ++i)scanf("%d", &b[i]);
		c[n] = min(a[n], b[n]);
		for (int i = n - 1; i >= 1; --i)
		{
			c[i] = min(max(c[i+1],a[i]),b[i]);
		}
		sort(c + 1, c + n + 1);
		double P = 1;
		double ans = 0;
		for (int i = 1; i + k - 1 <= n; ++i)
		{
			double p = 1.0*k / (n - i + 1);
			ans += c[i] * P *p;
			P -= p;
		}
		printf("%.15f\n", ans);
	}
	return 0;
}
/*
【trick&&吐槽】
ST-RMQ也能解决这道题,然而显然麻烦多了

【题意】
这题题意还是有些复杂啊!

我们转变一下,是这个意思:
给你两个数组a[](我们先要乘上100),b[],长度都为n,数字在[1,1e9]范围。

第一步:
要从中等概率任意选出k个li,
我们要对于每个li,选择一个ri(li<=ri<=n),val(li)尽可能大
所以我们定义val(l)为,找到一个r,使得res(l,r)尽可能大
而res(l,r)=min( max(a[i]~a[r]) , min(b[i]~b[r]) );

第二步:
在我们选出的k个li,对应了的k个best ri,形成了k个vali之后
我们选出最小的那个vali,作为这次选择的这k个li的ans。
而我们最终想要求得的是,ans的期望值。

【类型】
DP

【分析】
这道题要处理的步骤还真多。
对于第一步。在我们知道l的情况下,如何对应的最大val呢?
这个问题通过DP思维解决比较好。

处理问题要有由易到难的思维方式。
我们定义用c[i]表示val(i)
我们首先考虑到,对于i==n,显然答案是固定=min(a[n],b[n])
然后我们可以从右向左做DP转移。

c[i]=min( max(a[i]~a[r]) , min(b[i]~b[r]) );
c[i]=max( min(a[i],b[i]) , min(c[i+1],b[i]) );
可以化简为DP方程:c[i]=min(max(a[i],c[i+1]),b[i]);
意思是什么呢?
显然,对于i作为左界,在右界不为i的情况下,右界必然为i+1所对应的右界。
在我们把权值从c[i+1]到c[i]做转移的时候,传递过来以i+1作为左界的最优值,这可能会因为b[i]小而被局限。

这样子我们用O(n)的时间就把第一步求完了。然后转移到第二步。
======================================================
我们发现,自己要从n个c[]中任意取中k个值,而权值记做其中最小的一个。
于是,我们不妨把所有c[]按照从小到大排序。

然后这里我们依次扫描c[],我们求出c[i]为取出的k个数中最小数的概率p[i]
那么ans=∑c[i]*p[i]

显然p[1]=1*(k/n);
p[2]=(1-p[1])*(k/(n-1))
p[3]=(1-p[1]-p[2])*(k/(n-2))

意思是,选中最小的概率是k/n
否则没有选中最小,选中次小的概率=剩下的概率*k/(n-1)
否则没有选中最小和次小,选中次次小的概率=剩下的概率*k/(n-2)
依次类推。

这样这道题就做出来啦!

【时间复杂度&&优化】
O(n)

*/


你可能感兴趣的:(codeforces,脑洞,ST-RMQ,题库-CF,动态规划-线性DP)