题目大意:

n个人进入商店买东西,对于每个顾客都有T、C、P这3个数组,表示有Pj的概率第i个顾客在Tj的时间进入商店以Cj的价格买东西,每个顾客Pj的和小于等于1,保证每个时间只最多只有一个顾客可能会来,每个顾客只进入商店一次。一共有swords个物品,当一个顾客进来买东西的时候,售货员可以选择卖或不卖,她以之后的最大期望进行选择。问收银额的期望是多少。

解题思路:

当每个顾客可能来商店的时间只有一个的时候,题目比较简单,用dp[时间][剩下物品个数]的dp方程就可以解决。

当有顾客可能来商店的时间超过一个的时候,情况有点复杂,因为计算到下一个时间的时候,该顾客会不会出现的概率跟之前他有没有出现有关:如果之前他出现过了,那么这个时刻该顾客出现的概率为0;如果他之前没出现过,那个这个时间该顾客出现的概率是条件概率=原本的概率/(1-之前出现的概率和)。于是用一个位压缩状态来保存之前该顾客有没有出现。由于可能来商店的时间超过一个的顾客数量最多是24/2=12个,这样可以减少空间和时间。

之前没意识到这个是条件概率,一下子懵了,囧。。。。。

// 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>> ;
const double eps = 1e- ; double dp[<<][][]; class NewItemShop
{
public:
int peo[],cost[];double p[];
char str[];int sw;
int sam[]; double dfs(int mask,int swords,int tim){
double &s=dp[mask][swords][tim];
if(s>-0.5)return s;
if(tim==||swords==)return s=;
if(peo[tim]==-)return s=dfs(mask,swords,tim+);
if(peo[tim]==-){
s=p[tim]*max(dfs(mask,swords-,tim+)+cost[tim],dfs(mask,swords,tim+));
s+=(-p[tim])*dfs(mask,swords,tim+);
return s;
}else{
if(!(mask&(<<peo[tim])))return s=dfs(mask,swords,tim+);
s=p[tim]*max(dfs(mask^(<<peo[tim]),swords-,tim+)+cost[tim],dfs(mask^(<<peo[tim]),swords,tim+));
s+=(-p[tim])*dfs(mask,swords,tim+);
return s;
}
} double getMaximum(int swords, vector <string> customers)
{
clr(peo,-);sw=swords;
int n=customers.size();
int cnt=;
for(int i=;i<n;i++){
string s=customers[i];
int now=;double tmp=;sam[i]=;
vector<int>vec;vec.clear();
while(now<(int)s.size()){
int a,b;double c;
int k=;
while(now<(int)s.size()&&s[now]!=' '){
str[k]=s[now];k++;now++;
}
now++;
str[k]=;
sscanf(str,"%d,%d,%lf",&a,&b,&c);
peo[a]=i;cost[a]=b;p[a]=c//tmp;
tmp-=c/;
vec.push_back(a);
}
if(vec.size()==){
peo[vec[]]=-;
}else{
for(int i=;i<(int)vec.size();i++)
peo[vec[i]]=cnt;
cnt++;
}
}
for(int i=;i<<<cnt;i++)
for(int j=;j<=swords;j++)
for(int k=;k<=;k++)
dp[i][j][k]=-;
double ans=dfs((<<cnt)-,swords,);
return double(ans) ;
}
};

SRM 515 DIV1 550pt的更多相关文章

  1. topcoder srm 515 div1

    problem1 link 暴力枚举即可. problem2 link 一共有24小时,所以最多有24个顾客.设$f[x][y][z]$表示还剩下$x$把刀,现在时间是$y$,以及来过的顾客集合为$z ...

  2. Topcoder SRM 643 Div1 250<peter_pan>

    Topcoder SRM 643 Div1 250 Problem 给一个整数N,再给一个vector<long long>v; N可以表示成若干个素数的乘积,N=p0*p1*p2*... ...

  3. Topcoder Srm 726 Div1 Hard

    Topcoder Srm 726 Div1 Hard 解题思路: 问题可以看做一个二分图,左边一个点向右边一段区间连边,匹配了左边一个点就能获得对应的权值,最大化所得到的权值的和. 然后可以证明一个结 ...

  4. 图论 SRM 674 Div1 VampireTree 250

    Problem Statement      You are a genealogist specializing in family trees of vampires. Vampire famil ...

  5. SRM 449 div1 (practice)

    250pt: 暴力枚举所有的可能的情况就好了,求面积的时候我是用梯形的面积减去两个三角形的面积.. 550pt: 题意:给你一个蜂窝形状的特殊图形,有一些格子已经被占据了,问你将剩下的格子用1*2的砖 ...

  6. SRM 583 DIV1

    A 裸最短路. class TravelOnMars { public: int minTimes(vector <int>, int, int); }; vector<int> ...

  7. SRM 590 DIV1

    转载请注明出处,谢谢viewmode=contents">http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlov ...

  8. Topcoder SRM 602 div1题解

    打卡- Easy(250pts): 题目大意:rating2200及以上和2200以下的颜色是不一样的(我就是属于那个颜色比较菜的),有个人初始rating为X,然后每一场比赛他的rating如果增加 ...

  9. 状态压缩DP SRM 667 Div1 OrderOfOperations 250

    Problem Statement      Cat Noku has just finished writing his first computer program. Noku's compute ...

随机推荐

  1. 灰姑娘的水晶鞋(NOIP模拟赛Round 7)

    [问题描述] 传说中的水晶鞋有两种颜色:左边的水晶鞋是红色,右边的是蓝色,据说穿上它们会有神奇的力量. 灰姑娘要找到她所有的n双水晶鞋,它们散落在一条数轴的正半轴上,坐标各不相同,每双水晶鞋还有一个权 ...

  2. 算法详解(LCA&RMQ&tarjan)补坑啦!完结撒花(。◕ˇ∀ˇ◕)

    首先,众所周知,求LCA共有3种算法(树剖就不说了,太高级,以后再学..). 1.树上倍增(ST表优化) 2.RMQ&时间戳(ST表优化) 3.tarjan(离线算法)不讲..(后面补坑啦!) ...

  3. 高级全局API钩取 - IE连接控制

    @author: dlive @date: 2017/02/14 0x01 调试IE进程 常见网络连接库:ws2_32.dll(套接字),wininet.dll,winhttp.dll 使用Proce ...

  4. 动态内存管理详解:malloc/free/new/delete/brk/mmap

    c++ 内存获取和释放 new/delete,new[]/delete[] c 内存获取和释放 malloc/free, calloc/realloc 上述8个函数/操作符是c/c++语言里常用来做动 ...

  5. 如何在natTable表格上添加双击事件

    在项目当中,有时候需要双击表格中的某一行触发一个事件或者一次数据请求,这时候,我们就需要在表格中绑定相关事件,思路实际上很简单,添加一个绑定事件就ok了,那么怎么添加呢?简单实现如下: 1.创建绑定双 ...

  6. Delphi中的堆,栈

    来自:http://blog.163.com/liang_liu99/blog/static/884152162009111303756371/ --------------------------- ...

  7. AC日记——[HNOI2008]水平可见直线 bzoj 1007

    1007 思路: 维护一个下凸壳: 用单调栈来维护这玩意儿: 先将斜率排序: 然后判断栈顶元素和当前元素的交点x是否小于栈顶元素和栈顶上一个元素的交点x: 注意: 人神共愤的精度问题和输出空格问题: ...

  8. HDU 1171.Big Event in HDU-动态规划0-1背包

    Big Event in HDU Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others ...

  9. (寒假集训)Roadblock(最短路)

    Roadblock 时间限制: 1 Sec  内存限制: 64 MB提交: 9  解决: 5[提交][状态][讨论版] 题目描述 Every morning, FJ wakes up and walk ...

  10. [BZOJ5289][HNOI2018]排列(拓扑排序+pb_ds)

    首先确定将所有a[i]向i连边之后会形成一张图,图上每条有向边i->j表示i要在j之前选. 图上的每个拓扑序都对应一种方案(如果有环显然无解),经过一系列推导可以发现贪心策略与合并的块的大小和w ...