其他分享
首页 > 其他分享> > 【笔记】简单信息量计算

【笔记】简单信息量计算

作者:互联网

我们都听过基于比较的排序复杂度下限是 \(\mathcal{O}(N\log N)\) 的,那么下限是怎么求的?

我们知道长度为 \(n\) 的排列有 \(n!\) 个,这就是总信息量。每次排序,只会返回 \(>\) 或 \(<\) 只有两种情况。所以如果策略得当,进行 \(k\) 次比较最多可以区分 \(2^k\) 钟情况。排序需要满足 \(2^k \ge n!\),所以 \(k\) 是 \(\mathcal{O}(\log n! = n\log n)\) 级别的。

那么如果是 \(0/1\) 序列的基于比较的排序呢?总信息量是 \(2^n\),所以 \(k = \log 2^n = n\)。具体的策略是从前往后扫一遍即可得到最大值,然后再扫一遍即可知道每个 \(0/1\),也有实现更精密的线性做法。

再举一个简单的例子,有 \(n\) 份核酸检测样本,已知其中只有一份样本是阳性,怎样用最少的次数查出阳性样本。

由于只有一份是阳性,所以总信息量是 \(n\),而每次检测返回阴/阳两种情况,所以需要的次数是 \(k = \log n\) 次。具体的策略是混合一些样品,其中第 \(i\) 份样品混合了 \(n\) 个样本中二进制下第 \(i\) 位为 \(1\) 的样本。每次检测就可以知道阳性样本编号第 \(i\) 位是 \(0/1\)。

恰好有 \(a\) 个阳性时 \(k = \log \binom{n}{a} < \log 2^n = n\),所以可以构造比直接检测更优的方案。但现实中我们并不知道有多少个阳性。

Problem - 643F - Codeforces

难度跨度有点大。

这里我们是要求的是最大的总信息量。

那么我们看信息是什么。某头熊在某一天睡觉就是信息。\(n\) 头熊,最多有 \(p\) 头熊睡觉,有 \(t\) 天。那么最多可以区分的总信息量是 \(\sum\limits_{i = 0}^{p} \binom{n}{i}t ^ i\),同时我们又可以构造出这样一种策略,所以这就是最大信息量。

#define N 150
typedef unsigned ui;
int n, p, q; ui c[N], a[N], ed;
void calc(int x){
	rp(i, x)a[i] = n - i + 1;
	rp(i, x){
		int k = i;
		rp(j, x){
			ui w = gcd(a[j], k);
			k /= w, a[j] /= w;
			if(1 == k)break;
		}
	}
	c[x] = 1;
	rp(i, x)c[x] *= a[i];
}
int main() {
	read(n, p, q);
	p = min(p, n - 1);
	rep(i, 0, p)calc(i);
	rp(t, q){
		ui cur = 1, s = 0;
		rep(i, 0, p){
			s += cur * c[i];
			cur *= t;
		}
		ed ^= s * t;
	}
	cout << ed << endl;
	return 0;
}

标签:rp,log,信息量,样本,笔记,ui,简单,阳性
来源: https://www.cnblogs.com/7KByte/p/16340172.html