CF183D T-shirt

Posted zh-comld

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF183D T-shirt相关的知识,希望对你有一定的参考价值。

http://codeforces.com/problemset/problem/183/D

题解

我们可以对于每种\(size\)\(T-shirt\),设计一个\(dp\)

\(dp[i][j]\)表示这种\(T-shirt\)准备\(i\)件,转移到了第\(j\)个人,有\(i\)个人喜欢这种\(T-shirt\)的概率。

转移:

\(dp[i][j]=dp[i-1][j-1]*p[j][now]+dp[i][j-1]*(1-p[j][now]\)

最后我们把恰好转成至少,根据期望的线性性,取最大的前\(n\)个好了。

但是复杂度无法接受,因为我们只需要取前\(n\)个,所以可以贪心的选取最大的种类,从\(dp[i][j]\)扩展到\(dp[i+1][j]\)

代码

#include<bits/stdc++.h>
#define N 3002
#define M 302
using namespace std;
typedef long long ll;
int n,m;
long double dp[M][N],ans,pre[N],p[N][M],now[M];
inline ll rd()
    ll x=0;char c=getchar();bool f=0;
    while(!isdigit(c))if(c=='-')f=1;c=getchar();
    while(isdigit(c))x=(x<<1)+(x<<3)+(c^48);c=getchar();
    return f?-x:x;

int main()
    n=rd();m=rd();
    for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j)p[i][j]=(double)rd()/1000.0;
    
    for(int i=1;i<=m;++i)
        dp[i][0]=1;
        for(int j=1;j<=n;++j)dp[i][j]=dp[i][j-1]*(1-p[j][i]);
        now[i]=1-dp[i][n];
    
    for(int i=1;i<=n;++i)
        int k=0;
        for(int j=1;j<=m;++j)if(now[j]>now[k])k=j;
        if(!k)break;
        ans+=now[k];
        swap(pre,dp[k]);
        dp[k][0]=0;
        for(int j=1;j<=n;++j)dp[k][j]=pre[j-1]*p[j][k]+dp[k][j-1]*(1-p[j][k]);
        now[k]-=dp[k][n];
    
//  printf("%.12Lf",ans);//laji
    cout<<fixed<<setprecision(10)<<ans<<endl;
    return 0;

以上是关于CF183D T-shirt的主要内容,如果未能解决你的问题,请参考以下文章

CF799B T-shirt buying

T-shirt

hdu 1031 Design T-Shirt

HDU 1031 Design T-Shirt

hdoj-1031-Design T-Shirt

vjudge B - Design T-Shirt