标签:style code std span color 初始 lse pre push
期望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\n",dfs(1,0)); return 0; }
标签:style code std span color 初始 lse pre push
原文地址:https://www.cnblogs.com/lxy8584099/p/10316419.html