bzoj 1076: [SCOI2008]奖励关
Posted lxy8584099
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 1076: [SCOI2008]奖励关相关的知识,希望对你有一定的参考价值。
期望dp 记搜 带最优化
/************************************************************** Problem: 1076 User: lxy8584099 Language: C++ Result: Accepted Time:596 ms Memory:34144 kb ****************************************************************/ /* 概率题用记搜准没错 n<=15 可以压缩 32768 f i,j 表示i~m个宝物 状态为j的最大期望得分 f i,j = max f i+1,j 仅当 j满足能取到第i个宝物 */ #include<bits/stdc++.h> #define inf (2000000050) // 2e9 using namespace std; vector < int > vec[20]; int m,n,val[20]; double f[105][40050]; double max(double a, double b) {return a>b ? a : b;} double dfs(int k,int p) { if(k>m) return 0; // 只有m个宝物 if(f[k][p]!=-inf) return f[k][p]; // 记忆化 f[k][p]=0; // 初始化 for(int i=1;i<=n;i++) { bool flag=1; for(int j=0;j<vec[i].size()&&flag;j++) if(!(p&(1<<(vec[i][j]-1)))) flag=0; // 判断能否拿到此宝物 if(flag) f[k][p]+=max(dfs(k+1,p),dfs(k+1,p|(1<<(i-1)))+val[i]); // dp最优策略 else f[k][p]+=dfs(k+1,p); } f[k][p]/=n; return f[k][p]; } int main() { scanf("%d%d",&m,&n); for(int i=0;i<=m;i++) for(int j=0;j<=40000;j++) f[i][j]=-inf; for(int i=1,x;i<=n;i++) { scanf("%d",&val[i]); while(scanf("%d",&x)&&x) vec[i].push_back(x); } printf("%.6lf ",dfs(1,0)); return 0; }
以上是关于bzoj 1076: [SCOI2008]奖励关的主要内容,如果未能解决你的问题,请参考以下文章