题目大意:ios
n我的进入商店买东西,对于每一个顾客都有T、C、P这3个数组,表示有Pj的几率第i个顾客在Tj的时间进入商店以Cj的价格买东西,每一个顾客Pj的和小于等于1,保证每一个时间只最多只有一个顾客可能会来,每一个顾客只进入商店一次。一共有swords个物品,当一个顾客进来买东西的时候,售货员能够选择卖或不卖,她以以后的最大指望进行选择。问收银额的指望是多少。数组
解题思路:ide
当每一个顾客可能来商店的时间只有一个的时候,题目比较简单,用dp[时间][剩下物品个数]的dp方程就能够解决。spa
当有顾客可能来商店的时间超过一个的时候,状况有点复杂,由于计算到下一个时间的时候,该顾客会不会出现的几率跟以前他有没有出现有关:若是以前他出现过了,那么这个时刻该顾客出现的几率为0;若是他以前没出现过,那个这个时间该顾客出现的几率是条件几率=本来的几率/(1-以前出现的几率和)。因而用一个位压缩状态来保存以前该顾客有没有出现。因为可能来商店的时间超过一个的顾客数量最可能是24/2=12个,这样能够减小空间和时间。debug
以前没意识到这个是条件几率,一会儿懵了,囧。。。。。code
// BEGIN CUT HERE #include <sstream> /* */ #define debuging #ifdef debuging #define FIN {freopen("new.in" , "r" , stdin) ;} #define FOUT {freopen("new.out" , "w" , stdout) ;} #define OUT(x) {cout<< #x << " : " << x <<endl ;} #define ERR(x) {cout<<"#error: "<< x ; while(1) ;} #endif // END CUT HERE #ifndef debuging #define FIN ; #define FOUT ; #define OUT(x) ; #define ERR(x) ; #endif #include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #include <cmath> #include <vector> #include <map> using namespace std ; #define For(i , n) for(int i = 0 ; i < (n) ; ++i) #define SZ(x) (int)((x).size()) #define clr(a,b) memset(a,b,sizeof(a)) #define mpr(a,b) make_pair(a,b) typedef long long lint ; const int maxint = -1u>>2 ; const double eps = 1e-6 ; double dp[1<<12][24][25]; class NewItemShop { public: int peo[30],cost[30];double p[30]; char str[1000];int sw; int sam[30]; double dfs(int mask,int swords,int tim){ double &s=dp[mask][swords][tim]; if(s>-0.5)return s; if(tim==24||swords==0)return s=0; if(peo[tim]==-1)return s=dfs(mask,swords,tim+1); if(peo[tim]==-2){ s=p[tim]*max(dfs(mask,swords-1,tim+1)+cost[tim],dfs(mask,swords,tim+1)); s+=(1-p[tim])*dfs(mask,swords,tim+1); return s; }else{ if(!(mask&(1<<peo[tim])))return s=dfs(mask,swords,tim+1); s=p[tim]*max(dfs(mask^(1<<peo[tim]),swords-1,tim+1)+cost[tim],dfs(mask^(1<<peo[tim]),swords,tim+1)); s+=(1-p[tim])*dfs(mask,swords,tim+1); return s; } } double getMaximum(int swords, vector <string> customers) { clr(peo,-1);sw=swords; int n=customers.size(); int cnt=0; for(int i=0;i<n;i++){ string s=customers[i]; int now=0;double tmp=1;sam[i]=0; vector<int>vec;vec.clear(); while(now<(int)s.size()){ int a,b;double c; int k=0; while(now<(int)s.size()&&s[now]!=' '){ str[k]=s[now];k++;now++; } now++; str[k]=0; sscanf(str,"%d,%d,%lf",&a,&b,&c); peo[a]=i;cost[a]=b;p[a]=c/100/tmp; tmp-=c/100; vec.push_back(a); } if(vec.size()==1){ peo[vec[0]]=-2; }else{ for(int i=0;i<(int)vec.size();i++) peo[vec[i]]=cnt; cnt++; } } for(int i=0;i<1<<cnt;i++) for(int j=0;j<=swords;j++) for(int k=0;k<=24;k++) dp[i][j][k]=-1; double ans=dfs((1<<cnt)-1,swords,0); return double(ans) ; } };