• ●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;
    }
    

      

  • 相关阅读:
    ubuntu 安装nodejs
    在VMware下安装CentOS 7.6
    ogg基础知识整理
    Server2012多用户远程桌面及问题解决记录
    win10中批量新建文件夹
    word中去除所有table键
    PLSQL无法连接(不存在或找不到oci.dll)
    Oracle客户端安装及下载地址
    PLSQL官网下载地址
    问题解决:xampp中phpmyadmin“无法连接:无效的设置”
  • 原文地址:https://www.cnblogs.com/zj75211/p/8541993.html
Copyright © 2020-2023  润新知