洛谷 P2473 [SCOI2008] 奖励关


题目传送门


思路

确定算法

  • 首先,一个物品能不能选,还要看有没有选前提物品;
  • 其次,物品种类很少,只有 n ≤ 15 n \leq 15 n15
  • 因此,我们可以确定用 状压 d p dp dp 来求期望。

状态设计

  • 首先,肯定要有记录当前是第 i i i 轮的一维;
  • 其次,由于拿物品还要看已有物品集合,所以要有记录【当前已经拿了物品的集合】的一维;
  • d p i , s dp_{i, s} dpi,s 表示在 【第 1 1 1 i − 1 i - 1 i1 轮】 所拿到的物品集合为 s s s 时,第 i i i k k k 轮在最优情况下,所拿物品分值总和的期望。
    (为什么这么设计到状态转移会说)

状态转移

采用倒推(为什么不用正推等会说):

  1. 若目前状态 s s s 不能拿物品 k k k,那么: d p i , s + = d p i + 1 , s n dp_{i, s} += \frac{dp_{i + 1, s}}{n} dpi,s+=ndpi+1,s
  2. 若目前状态 s s s 可以拿物品 k k k,那么: d p i , s + = m a x ( d p i + 1 , s ∣ ( 1 < < ( k − 1 ) ) + p k , d p i + 1 , s ) n dp_{i, s} += \frac{max(dp_{i + 1, s | (1 << (k - 1))} + p_k, dp_{i + 1, s})}{n} dpi,s+=nmax(dpi+1,s(1<<(k1))+pk,dpi+1,s)分别对应选 k k k 与不选 k k k

问题一:为什么状态这么设计呢?

  1. 为了适应倒推的转移方程;
  2. 如果状态设计为【 d p i , s dp_{i, s} dpi,s 表示到第 i i i拿完后,且状态为 s s s 时,已有的分数的期望】(适应正推),就会影响后面物品的选择。因为有前驱物品集合的限制,这样 d p dp dp 就会有后效性,导致不正确。

问题二:为什么采用倒推呢 ?

  • 同样也是因为正推会有后效性。

边界条件

  • 对于 ∀ s ∈ [ 0 , 2 n − 1 ] \forall s \in [0, 2^n - 1] s[0,2n1] d p n + 1 , s dp_{n + 1, s} dpn+1,s 均为 0 0 0
  • 含义就是:在 1 1 1 n n n 轮选完的状态 s s s 下,已经结束了,不能再选了,因此期望为 0 0 0

答案

  • 就是 d p 1 , 0 dp_{1, 0} dp1,0,含义就是:还没有开始时,一个物品都没选的状态,所能得到的期望分。

复杂度

  • 空间: O ( k × n ) O(k \times n) O(k×n)
  • 时间: O ( k × n × 2 n ) O(k \times n \times 2^n) O(k×n×2n)

代码

#include 

using namespace std;

const int maxn = 1e2 + 7;
const int maxs = (1 << 15) + 7;

int n, m;
struct Prize {int p, s;} a[maxn];
double dp[maxn][maxs];
int main () {
	scanf("%d%d", &n, &m);
	for (int i = 1, x; i <= m; ++i) {
		scanf("%d", &a[i].p);
		while (1) {
			scanf("%d", &x);
			if (!x) break;
			a[i].s |= 1 << (x - 1);
		}
	}
	
	for (int i = n; i >= 1; --i) {
		for (int s = 0; s < (1 << m); ++s) {
			for (int k = 1; k <= m; ++k) {
				if ((s & a[k].s) != a[k].s) dp[i][s] += dp[i + 1][s];
				else dp[i][s] += max(dp[i + 1][s], dp[i + 1][s | (1 << (k - 1))] + a[k].p);
			}
			dp[i][s] /= m;
		}
	}
	printf("%.6lf\n", dp[1][0]);
	return 0;
}

反思

  1. 依旧只想出了状态,没对转移方程;
  2. 发现对这种 最优值期望 的转移方程我总会写成 最优值 的转移方程,并没有很好地理解期望的含义及计算方法;
  3. 运用 倒推 的意识少;
  4. 那种【前面选择】影响【后面选择】的 d p dp dp 最好用倒推,因为先考虑后面,就不用管前面的影响了。

你可能感兴趣的:(动态规划,概率与期望,题解,动态规划,概率与期望,状态压缩)