[CF183D]T-shirt

题目大意:

有\(n(n\le3000)\)个人和\(m(m\le300)\)种T恤,每个人都有一种喜欢的T恤,你知道每个人喜欢每种T恤的概率\(p_{i,j}\)。

请你选定\(n\)件体恤的种类,人们会按照编号从\(1\sim n\)挑选T恤,如果剩下还有他喜欢的,则会选走,否则不变。

求送出T恤件数的最大期望。

思路:

用\(f[i][j][k]\)表示对于第\(i\)件T恤,前\(j\)个人中有\(k\)个人喜欢的概率。\(g[i][j]\)表示对于第\(i\)种T恤,选取\(j\)件时对答案贡献的期望值。

\(f\)的转移方程显然,同时也不难得到\(g\)的状态转移方程:

\[g[i][j]=\sum_{k=0}^jk\cdot f[i][n][k]+\sum_{k=j+1}^nj\cdot f[i][n][k]
\]

这样的动态规划是\(\mathcal O(nm^2)\)的。

考虑优化,对\(g\)的相邻两项作差,得到:

\[g[i][j+1]-g[i][j]=1-\sum_{k=0}^j f[i][n][k]
\]

显然这个差值\(\Delta\)表示再加入一条这样的T恤对答案的贡献,而它又是单调递减的,因此每次选取最大的\(\Delta\)更新一定最优。

一开始只计算\(f[i][j][0]\)和\(\Delta[i][0]\),然后每次选取\(\Delta\)最大的T恤更新答案,然后对相应的T恤进行更新\(f\)和\(\Delta\)即可。这样可以同时省掉\(f\)的第三维。

时间复杂度\(\mathcal O(nm+n^2)\)。

源代码:

#include<cstdio>
#include<cctype>
#include<algorithm>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return x;
}
const int N=3001,M=301;
double p[N][M],f[M][N],del[M];
//f[i][j]: 第i种衣服前j个人有cnt[i]个人喜欢的概率
//del[i]: 新加入第i种衣服对答案的贡献
int main() {
const int n=getint(),m=getint();
for(register int i=1;i<=n;i++) {
for(register int j=1;j<=m;j++) {
p[i][j]=getint()/1000.;
}
}
for(register int i=1;i<=m;i++) {
f[i][0]=1;
for(register int j=1;j<=n;j++) {
f[i][j]=f[i][j-1]*(1-p[j][i]);
}
del[i]=1-f[i][n];
}
double ans=0;
for(register int i=0;i<n;i++) {
const int k=std::max_element(&del[1],&del[m]+1)-del;
ans+=del[k];
for(register int i=n;i>=1;i--) {
f[k][i]=f[k][i-1]*p[i][k];
}
f[k][0]=0;
for(register int i=2;i<=n;i++) {
f[k][i]+=f[k][i-1]*(1-p[i][k]);
}
del[k]-=f[k][n];
}
printf("%.12f\n",ans);
return 0;
}

[CF183D]T-shirt的更多相关文章

  1. 新概念英语(1-11)Is this your shirt ?

    Is this your shirt?Whose shirt is white? A:Whose shirt is that? Is this your shirt, Dave? Dave:No si ...

  2. Windows 10文件夹Shirt+鼠标右键出现“在此处打开命令窗口”

    Windows 10文件夹Shirt+鼠标右键出现“在此处打开命令窗口” Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\Directo ...

  3. 【CF183D】T-shirt(动态规划,贪心)

    [CF183D]T-shirt(动态规划,贪心) 题面 洛谷 CodeForces 题解 \(O(n^2m)\)的暴力懒得写了,比较容易,可以自己想想. 做法是这样的,首先我们发现一个结论: 对于某个 ...

  4. SELECT s.* FROM person p INNER JOIN shirt s ON s.owner = p.id WHERE p.name LIKE 'Lilliana%' AND s.color <> 'white';

    SELECT s.* FROM person p INNER JOIN shirt sON s.owner = p.idWHERE p.name LIKE 'Lilliana%'AND s.color ...

  5. [Eclipse插件] Eclipse设置Tab键为空格(ctrl+shirt+f格式化生效)!

    自定义format格式,用空格替换Tab键,ctrl+shit+f格式化后生效: 设置Eclipse中按Tab键为4个空格,这里标记下! Window-->Preferences-->Ja ...

  6. javascript arguments(转)

    什么是arguments arguments 是是JavaScript里的一个内置对象,它很古怪,也经常被人所忽视,但实际上是很重要的.所有主要的js函数库都利用了arguments对象.所以agru ...

  7. Linux.NET实战手记—自己动手改泥鳅(下)

    在上回合中,我们不痛不痒的把小泥鳅的数据库从只能供在Windows下运行的Access数据库改为支持跨平台的MYSQL数据库,毫无营养的修改,本回合中,我们将把我们修改后得来的项目往Linux中部署. ...

  8. MySQL基础

    数据库操作 ---终端使用数据库 mysql -u root -p 之后回车键 输入密码 ---显示所有数据库: show databases; ---默认数据库: mysql - 用户权限相关数据 ...

  9. Swift3.0P1 语法指南——构造器

    原档:https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programmi ...

随机推荐

  1. python 爬虫简单的demo

    ''' @author :Eric-chen @contact:809512722@qq.com @time :2018/1/3 17:55 @desc :通过爬取http://movie.douba ...

  2. 用jquery实现toast的原理

    function toast(mess){ var str='<div class="mess"><span></span></div&g ...

  3. 一步一步搭建 oracle 11gR2 rac + dg 之前传 (一)【转】

    一步一步在RHEL6.5+VMware Workstation 10上搭建 oracle 11gR2 rac + dg  之前传 (一) 转自 一步一步搭建 oracle 11gR2 rac + dg ...

  4. nginx自定义500,502,504错误页面无法跳转【转】

    1.自定一个页面,这个页面是一个链接地址可以直接访问的. 以下是nginx的配置: location / {            proxy_pass http://tomcat_app108;   ...

  5. iOS开发之删除Provisioning Profiles方法

    1.在finder下打开go -> go to folder输入: ~/Library/MobileDevice/Provisioning Profiles 2.查看上面的列表,按照时间顺序删除 ...

  6. MinGw 和 cygwin 的区别和联系

    原创 by zoe.zhang .......................................................... 1. windows与Linux操作系统的不同   ...

  7. 数据库-python操作mysql(pymsql)

    pymsql是Python中操作MySQL的模块,其使用方法和MySQLdb几乎相同 一:安装pymysql pip3 install pymysql 二:使用pytmysql # -*- codin ...

  8. No.19 selenium学习之路之os模块

    os模块没有什么好说的,直接看实例就可以了 读取文件内容: open只能读文件的内容,不能读文件夹的内容 常用方法: 1. os.name——判断现在正在实用的平台,Windows 返回 ‘nt'; ...

  9. git —— Feature分支

    添加新功能时,新建feature分支 分支上开发完成后,再进行合并.最后删除feature分支 $ git checkout -b feature-vulcan 开发完毕后,切换回添加的分支,进行合并 ...

  10. [USACO16OPEN]248

    传送门啦 分析: 一个裸的区间dp,我们只需要注意合并的时候并不像2048那样加倍,每次都加1就好了 #include <iostream> #include <cstring> ...