coin
### Decsription

数据范围:\(n<=3000,m<=300\),保证\(\forall i,\sum\limits_{j}p_{ij}=1000\)
Solution
日常期望算不对。。
首先比较明显的一点是,每种类型是独立的,我们可以分开来考虑
先来想一个比较直接的dp
用\(a[i][j]\)表示第\(i\)个人最喜欢\(j\)的概率,记\(f[c][i][j]\)表示前\(i\)个人里面恰好有\(j\)个人最喜爱类型\(c\),转移显然:
\]
再考虑用\(g[i][j]\)表示第\(i\)种钞票携带了\(j\)张,期望拿走的数量,那么有转移:
g[i][j]&=\sum\limits_{k=0}^mmin(k,j)*f[i][n][k]\\
&=\sum\limits_{k=0}^j k*f[i][n][k]+\sum\limits_{k=j+1}^mj*f[i][n][k]\\
\end{aligned}
\]
然后我们就可以用一个背包求出答案了,但是这样无论是空间还是时间都很爆炸
考虑\(\nabla g[i][j]=g[i][j]-g[i][j-1]\),也就是\(\nabla g[i][j]=\sum\limits_{k=j}^m f[i][n][k]\),首先注意到\(f[i][n][k]\)在\(i\)确定的情况下大小一定是随着\(k\)的增大而增大的,然后再看回这个\(\nabla g[i][j]\),显然这个东西的值应该是非负的,并且当\(i\)一定,\(\nabla g[i][j]\)的值随着\(j\)的增大而单调不升
所以我们可以得到一个结论,当\(i\)确定的时候,\(g[i][j]\)是不降的,并且增幅逐渐下降
然后又因为每种钞票是独立的,我们可以考虑一个贪心
枚举\(n\)张钞票的每一张都选什么,对于每一种钞票\(c\),我们维护一个隐性的\(p_c\)(说是“隐性”是因为在实现的时候你并不需要真的去维护这么一个东西),表示钞票\(c\)当前已经取了\(p_c\)张,那么从贪心的角度来看,我们当前枚举到的这张钞票,肯定希望新加入这张钞票之后,对应的\(g[c]\)的增幅最大,所以就可以得到一个大致的流程:从\(1\)到\(n\)枚举每一张钞票选什么,对于第\(i\)张钞票,\(O(m)\)求得最大的\(g\)的增幅,加入答案,然后对于选择的这个种类\(c\),更新其\(g\)值
现在的问题就是怎么维护增幅,为了方便下面只针对确定的\(c\)类钞票进行表述
一开始的时候\(p_c=0\),\(g[c][0]\)到\(g[c][1]\)的增幅是很好计算的,\(\nabla g[c][1]=1-\prod\limits_{i=1}^n(1-a[i][c])\),但是\(\nabla g[c][2]\)看起来就不能那么直接地进行计算了,所以我们还是看回这个式子:\(\nabla g[i][j]=\sum\limits_{k=j}^mf[i][n][k]=1-\sum\limits_{k=0}^{j-1}f[i][n][k]\),那所以我们只要对于第\(c\)种钞票维护\(f[c][i][j]\)就好,然后维护一个\(sum[c]=\sum\limits_{k=0}^{p_c}f[c][n][k]\),每次更新完\(f[c]\)之后把\(f[c][n][p_c]\)加到\(sum[c]\)里面就好了
接下来就是空间怎么解决:对于\(f[c][i][j]\)来说,我们是按照\(j\)进行dp的,显然\(j\)那维可以滚动掉,\(f[c][][j]\)到\(f[c][][j+1]\)的更新是\(O(n)\)的,然后我们就获得了一个\(O(nm)\)的算法
mark:(弱智操作)谁告诉你听算期望的时候可以钦定顺序的???
Code
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=3010,M=310;
double sum[N],f[2][M][N];
double a[N][M];
int now[M],pre[M];
int n,m;
double ans;
void dp(int x){
swap(now[x],pre[x]);
int Now=now[x],Pre=pre[x];
f[Now][x][0]=0;
for (int i=1;i<=n;++i)
f[Now][x][i]=f[Now][x][i-1]*(1-a[i][x])+f[Pre][x][i-1]*a[i][x];
}
int main(){
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
#endif
int x;
scanf("%d%d",&n,&m);
for (int i=1;i<=n;++i)
for (int j=1;j<=m;++j)
scanf("%d",&x),a[i][j]=1.0*x/1000;
for (int i=1;i<=m;++i){
f[0][i][0]=1;
for (int j=1;j<=n;++j)
f[0][i][j]=f[0][i][j-1]*(1-a[j][i]);
sum[i]=f[0][i][n];
}
for (int i=1;i<=m;++i) now[i]=0,pre[i]=1;
int which;
double mx;
for (int j=1;j<=n;++j){
mx=0; which=-1;
for (int i=1;i<=m;++i)
if (1-sum[i]>mx)
which=i,mx=1-sum[i];
ans+=mx;
dp(which);
sum[which]+=f[now[which]][which][n];
}
printf("%.10lf\n",ans);
}
coin的更多相关文章
- [LeetCode] Coin Change 硬币找零
You are given coins of different denominations and a total amount of money amount. Write a function ...
- 洛谷P2964 [USACO09NOV]硬币的游戏A Coin Game
题目描述 Farmer John's cows like to play coin games so FJ has invented with a new two-player coin game c ...
- [luogu2964][USACO09NOV][硬币的游戏A Coin Game] (博弈+动态规划)
题目描述 Farmer John's cows like to play coin games so FJ has invented with a new two-player coin game c ...
- LeetCode Coin Change
原题链接在这里:https://leetcode.com/problems/coin-change/ 题目: You are given coins of different denomination ...
- ACM Coin Test
Coin Test 时间限制:3000 ms | 内存限制:65535 KB 难度:1 描述 As is known to all,if you throw a coin up and let ...
- HDOJ 2069 Coin Change(母函数)
Coin Change Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- leetcode:Coin Change
You are given coins of different denominations and a total amount of money amount. Write a function ...
- UVa 674 Coin Change【记忆化搜索】
题意:给出1,5,10,25,50五种硬币,再给出n,问有多少种不同的方案能够凑齐n 自己写的时候写出来方案数老是更少(用的一维的) 后来搜题解发现,要用二维的来写 http://blog.csdn. ...
- Epic - Coin Change
Something cost $10.25 and the customer pays with a $20 bill, the program will print out the most eff ...
- UVA 674 Coin Change (DP)
Suppose there are 5 types of coins: 50-cent, 25-cent, 10-cent, 5-cent, and 1-cent. We want to make c ...
随机推荐
- 查看Oracle数据库中的,已经连接好的..当前用户状况
参考: http://stackoverflow.com/questions/1043096/how-to-list-active-open-connections-in-oracle 以sys身份连 ...
- python 回溯法 子集树模板 系列 —— 1、8 皇后问题
问题 8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同一列或同一斜线上,问有多少种摆法. 分析 为了简化问题,考虑到8个皇后不同行,则每一行放置一个皇后,每一行的 ...
- Arcgis安装要素
1. ArcGIS安装过程中需将用户名改为计算机名,该计算机名称时需要新建对话框. 2. ArcGIS Server安装过程中要设置ArcGISWebServices用户的读写权限,即设置ASP.NE ...
- 微信小程序之地理位置授权 wx.getLocation
1. 授权地理位置 点击按钮,弹出授权弹窗,点击允许后,在以后的操作中可以随时获取到用户地理位置 点击拒绝后,将无法获取到地理位置,也无法再次点击弹出弹窗. <button bindtap='o ...
- Redis基本数据类型介绍笔记
Redis 数据类型 Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合). String(字符串) st ...
- idea使用actiBPM插件中文乱码
idea 安转activiti插件后,编辑流程图发现保存后中文乱码,并且idea的字符集(Settings—>Editor—>File Encodings)已经设置为UTF-8,流程图中中 ...
- 个人新站 【EXP技术分享博客】 落成~ 全新的技术资源~ 欢迎莅临~
对的,我筹备了大半年的个站技术网站正式开张了~ EXP技术分享博客: http://exp-blog.com CSDN上面大部分文章已经迁移过去了,以后也会更多地在新站点更新~ 为了庆祝新站开张,近期 ...
- Jenkins下载安装
Jenkins是什么? Jenkins是一个功能强大的应用程序,允许持续集成和持续交付项目,无论用的是什么平台.这是一个免费的源代码,可以处理任何类型的构建或持续集成.集成Jenkins可以用于一些测 ...
- Mac OS系统 sublime text3 常用快捷键记录
个人觉得下面这些个常用的快捷键,还是有必要熟练使用的: 符号说明: ⌘:command ⌃:control ⌥:option ⇧:shift ↩:enter ⌫:delete cmd+n 新建文件(n ...
- Mininet安装
Mininet 安装 根据SDNLAB上的实验进行安装.连接地址 需要注意的是切换到用户目录下进行clone github上的源码. 1.卸载之前安装的Mininet 最好是先到目录下看是否有这些文件 ...