SRM 515 DIV1 550pt

題目大意: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) ;
    }
};
View Code
相關文章
相關標籤/搜索