●BZOJ 1076 [SCOI2008]奖励关

题链:

http://www.lydsy.com/JudgeOnline/problem.php?id=1076
题解:

期望dp。
(模糊的题意,2333)
题中的:"现在决定不吃的宝物以后也不能再吃"应该是指:当前可以吃时,即面临选择时,如果选择了不吃,那么以后就都不能吃该宝物了。
(如果不这么理解的话,感觉dp转移解释不通)

dp[i][S]表示到了第i次机会,已经吃了的糖果的集合为S时,以后(包括这次)所期望的最高得分。
依次枚举这次的随机出来的宝物j:
如果满足前提条件:
dp[i][S]+=max(dp[i+1][S],dp[i+1][S|idx(j)]+val[j])/N
如果不满足前提条件,那么就只有一种转移了:
dp[i][S]+=dp[i+1][S]/N

为什么这样转移就可以满足题中的那个鬼畜的"以后就不能吃的"限制了呢。
先看第一个转移:如果当前选择了不吃更优的话,那么以后当然也不会吃的。
如果当前选择了吃更优,那么以后也一定会吃。
(换句话说,不会存在这样一种dp转移:在后来吃了这个宝物,但是现在可以吃的时候却选择不吃了)
然后第二个转移:因为手动"更改"了一下题意,这么转移就当然没问题啦。

代码:

#include<bits/stdc++.h>
using namespace std;
double dp[105][1<<15];
int pre[20],val[20];
int N,K;
int idx(int i){
	return 1<<(i-1);
}
int main(){
	ios::sync_with_stdio(0);
	cin>>K>>N;
	for(int i=1,x;i<=N;i++){
		cin>>val[i];
		while(cin>>x&&x) pre[i]|=idx(x);
	}
	for(int i=K;i>=1;i--)
		for(int S=0;S<(1<<N);S++)
			for(int j=1;j<=N;j++){
				double k=1.0/N;

				/*注释的是枚举的S表示来源dp[i+1][S]的S,注意if的嵌套。
				 (为了满足题意:当前宝物可吃但是选择不吃那么以后就不能吃了,所以只有不满足前提条件是才能执行else语句)
				if((S&pre[j])==pre[j]){
					if(!(S&idx(j))) continue;
					dp[i][S]+=max(k*(dp[i+1][S]+val[j]),k*dp[i+1][S]);
					dp[i][S^idx(j)]+=max(k*(dp[i+1][S]+val[j]),k*dp[i+1][S^idx(j)]);
				}
				else dp[i][S]+=k*dp[i+1][S];*/

				//以下是枚举的S表示当前dp[i][S]的那个S
				if((S&pre[j])==pre[j])
					dp[i][S]+=max(k*dp[i+1][S],k*(dp[i+1][S|idx(j)]+val[j]));
				else dp[i][S]+=k*dp[i+1][S];
			}
	cout<<fixed<<setprecision(6)<<dp[1][0]<<endl;
	return 0;
}

  

原文地址:https://www.cnblogs.com/zj75211/p/8541993.html

时间: 2024-10-02 20:40:03

●BZOJ 1076 [SCOI2008]奖励关的相关文章

bzoj 1076: [SCOI2008] 奖励关 题解

[原题] 1076: [SCOI2008]奖励关 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 684  Solved: 403 [Submit][Status] Description 你正在玩你最喜欢的电子游戏,并且刚刚进入一个奖励关.在这个奖励关里,系统将依次随机抛出k次宝物,每次你都可以选择吃或者不吃(必须在抛出下一个宝物之前做出选择,且现在决定不吃的宝物以后也不能再吃). 宝物一共有n种,系统每次抛出这n种宝物的概率都相同且相互独立.

[BZOJ 1076][SCOI2008]奖励关

1076: [SCOI2008]奖励关 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2707  Solved: 1423[Submit][Status][Discuss] Description 你正在玩你最喜欢的电子游戏,并且刚刚进入一个奖励关.在这个奖励关里,系统将依次随机抛出k次宝物,每次你都可以选择吃或者不吃(必须在抛出下一个宝物之前做出选择,且现在决定不吃的宝物以后也不能再吃). 宝物一共有n种,系统每次抛出这n种宝物的概率都相同且相

[BZOJ 1076][SCOI2008]奖励关(期望+状压Dp)

Description 你正在玩你最喜欢的电子游戏,并且刚刚进入一个奖励关.在这个奖励关里,系统将依次随机抛出k次宝物, 每次你都可以选择吃或者不吃(必须在抛出下一个宝物之前做出选择,且现在决定不吃的宝物以后也不能再吃).  宝物一共有n种,系统每次抛出这n种宝物的概率都相同且相互独立.也就是说,即使前k-1次系统都抛出宝物1( 这种情况是有可能出现的,尽管概率非常小),第k次抛出各个宝物的概率依然均为1/n. 获取第i种宝物将得到Pi 分,但并不是每种宝物都是可以随意获取的.第i种宝物有一个前

BZOJ 1076 SCOI2008 奖励关 期望状压DP

题目大意:给定k次弹出宝物的机会,每次随机弹出n种宝物的机会,如果吃过这种宝物的所有前提宝物就可以吃这种宝物,求最优策略的期望得分 看到数据范围果断状压DP- - 不看数据范围害死人- - 至于吃还是不吃 这是个问题 对于这种最优策略的期望DP 我们一般都是从后往前推 枚举每次出现宝物 枚举此时的状态 枚举宝物是哪种 如果当前的宝物可以吃 就在吃与不吃的后继状态中选择最大值加到当前状态上 如果当前的宝物不能吃 只能选择不吃的后继状态加到当前状态上 最后输出f[1][0]就是答案 #include

1076: [SCOI2008]奖励关( dp )

期望状压dp.... ------------------------------------------------------------------ #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #include<iostream> #define clr( x , c ) memset( x , c , sizeof( x ) ) #def

【BZOJ】1076 [SCOI2008]奖励关

[算法]期望DP+状压DP [题解]f[i][j]表示第i轮,状态为j的期望得分. 期望DP一般倒着做,因为正着做的话会可能从很多状态都可以满足当前选择,需要双重枚举. 而如果倒着做的话,是已知当前状态枚举后面的选择,只需单重枚举. 倒着枚举,则f[i][j]表示当前第i轮状态为j,枚举第i+1轮的宝物得到状态j'. 题目中出现了最优决策难以和期望DP结合,那么使用状压就可以避开决策问题. 得分的来源是枚举的宝物,所以正枚和倒枚没有本质区别,这也是套路.

1076: [SCOI2008]奖励关

链接 思路 状压dp,dp[i][s]表示当前是第i次选择,吃过的宝物的状态是s,的期望得分. 如果一个宝物可以吃,那么可以选择吃或不吃,取最大的. zz的我:50010的空间开成了500100,然后提示tle,醉了.. 代码 1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<iostream> 5 #include<cmath> 6 7 using n

BZOJ1076: [SCOI2008]奖励关

1076: [SCOI2008]奖励关 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1669  Solved: 921[Submit][Status][Discuss] Description 你正在玩你最喜欢的电子游戏,并且刚刚进入一个奖励关.在这个奖励关里,系统将依次随机抛出k次宝物, 每次你都可以选择吃或者不吃(必须在抛出下一个宝物之前做出选择,且现在决定不吃的宝物以后也不能再吃).  宝物一共有n种,系统每次抛出这n种宝物的概率都相同且

bzoj1076: [SCOI2008]奖励关(期望dp+状压dp)

1076: [SCOI2008]奖励关 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2989  Solved: 1557[Submit][Status][Discuss] Description 你正在玩你最喜欢的电子游戏,并且刚刚进入一个奖励关.在这个奖励关里,系统将依次随机抛出k次宝物,每次你都可以选择吃或者不吃(必须在抛出下一个宝物之前做出选择,且现在决定不吃的宝物以后也不能再吃). 宝物一共有n种,系统每次抛出这n种宝物的概率都相同且相