【10.5校内测试】【DP】【概率】


转移都很明显的一道DP题。按照不优化的思路,定义状态$dp[i][j][0/1]$表示吃到第$i$天,当前胃容量为$j$,前一天吃(1)或不吃(0)时能够得到的最大价值。
因为有一个两天不吃可以复原容量的定义,所以需要前一天的状态。
而注意,容量表示的是当前第$i$天吃之前的容量。
然后考虑压缩空间,将天数滚动。要注意的是滚动过后$now$指向的是$i$后一天的状态,因此刷表更新。
#include<bits/stdc++.h>
using namespace std; int n, m;
int a[], dp[][][], ap[]; int main() {
freopen("buffet.in", "r", stdin);
freopen("buffet.out", "w", stdout);
scanf("%d%d", &n, &m);
int ans = ;
for(int i = ; i <= n; i ++) scanf("%d", &a[i]);
ap[] = m;
for(int i = ; i <= n; i ++) ap[i] = ap[i-] * / ;
int now = ;
memset(dp[now], -, sizeof(dp[now]));
dp[][][] = ;
for(int i = ; i <= n; i ++) {
now ^= ;
memset(dp[now], -, sizeof(dp[now]));
for(int j = ; j <= n; j ++) {
if(~dp[now^][j][]) {
dp[now][][] = max(dp[now][][], dp[now^][j][]);
dp[now][j+][] = max(dp[now][j+][], dp[now^][j][] + min(a[i], ap[j]));
}
if(~dp[now^][j][]) {
dp[now][j+][] = max(dp[now][j+][], dp[now^][j][] + min(a[i], ap[j]));
dp[now][j-][] = max(dp[now][j-][], dp[now^][j][]);
}
}
}
for(int i = ; i <= n; i ++)
ans = max(ans, max(dp[now][i][], dp[now][i][]));
printf("%d", ans);
return ;
}


概率神题,三校只有$yuli$dalao$A$掉了%%%%
非常神奇的记忆化搜索,就算我能把式子推出来也会弄晕的QAQ
定义$dp[i][j]$表示当前剩余$i$个人,当前编号为$j$的人的存活概率。枪在当前1号手中。
注意这个当前,表示的是此时剩下来的人重新从0编号。
可以推出转移式子:$dp[i][j]=q*dp[i-1][j-1]+(1-q)*dp[i][(j-kmodi+i)modi]$,$q$表示当前这枪打出去能打出来的概率。$q=(i-1)/C$,因为当前子弹比人数要少1。前一个式子是打出了这个枪,于是0死了,j在剩下的人中号数要-1,(1把枪移交2相当与2变为了现在的1),后面的式子是打了空枪,枪移交给后面第k个人,同样也是把整个队列往前移k位。
观察式子可以发现,$dp[i-1][j-1]$我们可以在记忆化搜索中递归求得,而后面$dp[i][(j-kmodi+i)modi]$是与$dp[i][j]$同层的,考虑怎么求得。
可以发现,如果一直打空枪,从$j$开始,一定可以通过环走回$j$。所以在递归边界式子变为$dp[i][j]=o+(1-q)^ndp[i][j]$,其中每个$(1-q)$虽然不同,但在搜索过程中可以顺便算出来。$o$表示的是在以后的层数中可以求得的,因为我们可以把$dp[i][(j-kmodi+i)modi]$带入最开始的转移式,再把它们按层数分离。然后就按分离出来的式子将每一步更新即可。
过程中记忆化即可。然后概率要用逆元,可以预处理出来。
#include<bits/stdc++.h>
#define LL long long
#define mod 1000000009
using namespace std; int T, N, C, K; int vf[];
int dp[][], vis[][];
LL mpow(int a, LL b) {
LL ans = ;
for(; b; b >>= , a = 1ll * a * a % mod)
if(b & ) ans = 1ll * ans * a % mod;
return ans;
} int dfs(int res, int pos, int oo, int gl) {
if(pos == -) return ;
if(res == ) return ;
if(vis[res][pos] && dp[res][pos] == -) {//同层中走回来了 可以直接算
dp[res][pos] = 1ll * oo * mpow(( - gl + mod) % mod, mod - ) % mod;
return dp[res][pos];
}
if(vis[res][pos]) return dp[res][pos];//记忆化
vis[res][pos] = ;
dfs(res, (pos - K % res + res) % res, (oo + 1ll * gl * (res - ) % mod * vf[C] % mod * dfs(res - , pos - , , ) % mod) % mod, 1ll * gl * (C - res + ) % mod * vf[C] % mod);//子弹共有res-1个
if(~dp[res][pos]) return dp[res][pos];
dp[res][pos] = (1ll * (res - ) * vf[C] % mod * dfs(res - , pos - , , ) % mod + 1ll * (C - res + ) * vf[C] % mod * dp[res][(pos - K % res + res) % res] % mod) % mod;
return dp[res][pos];
} int main() {
freopen("gun.in", "r", stdin);
freopen("gun.out", "w", stdout);
scanf("%d", &T);
for(int i = ; i <= ; i ++) vf[i] = mpow(i, mod - );
while(T --) {
memset(vis, , sizeof(vis));
memset(dp, -, sizeof(dp));
scanf("%d%d%d", &N, &C, &K);
for(int i = ; i < N; i ++)
printf("%d ", dfs(N, i, , ));
printf("\n");
}
}
【10.5校内测试】【DP】【概率】的更多相关文章
- 【10.17校内测试】【二进制数位DP】【博弈论/预处理】【玄学(?)DP】
Solution 几乎是秒想到的水题叻! 异或很容易想到每一位单独做贡献,所以我们需要统计的是区间内每一位上做的贡献,就是统计区间内每一位是1的数的数量. 所以就写数位dp辣!(昨天才做了数字统计不要 ...
- 【10.31校内测试】【组合数学】【记忆化搜索/DP】【多起点多终点二进制拆位Spfa】
Solution 注意取模!!! Code #include<bits/stdc++.h> #define mod 1000000007 #define LL long long usin ...
- 【10.29校内测试】【线段树】【DP】【二进制Trie树求最小值最大】
Solution 标程太暴力惹QAQ 相当于是26棵线段树的说QAQ 不过我写了另一种写法,从大到小枚举每一个字母,标记字典序在这个字母之上的位置为1,每次都建一棵线段树,维护1的数量,即区间和. 修 ...
- 【10.26校内测试】【状压?DP】【最小生成树?搜索?】
Solution 据说正解DP30行??? 然后写了100行的状压DP?? 疯狂特判,一算极限时间复杂度过不了aaa!! 然而还是过了....QAQ 所以我定的状态是待转移的位置的前三位,用6位二进制 ...
- 【10.4校内测试】【轮廓线DP】【中国剩余定理】【Trie树+博弈】
考场上几乎是一看就看出来轮廓线叻...可是调了两个小时打死也过不了手出样例!std发下来一对,特判对的啊,转移对的啊,$dp$数组竟然没有取max!!! 某位考生当场死亡. 结果下午又请了诸位dala ...
- 【10.3校内测试【国庆七天乐!】】【DP+组合数学/容斥】【spfa多起点多终点+二进制分类】
最开始想的暴力DP是把天数作为一个维度所以怎么都没有办法优化,矩阵快速幂也是$O(n^3)$会爆炸. 但是没有想到另一个转移方程:定义$f[i][j]$表示每天都有值的$i$天,共消费出总值$j$的方 ...
- 【10.11校内测试】【优先队列(反悔贪心)】【莫队】【stl的应用??离线处理+二分】
上次做过类似的题,原来这道还要简单些?? 上次那道题是每天可以同时买进卖出,所以用两个优先队列,一个存买进,一个存卖出(供反悔的队列). 这道题实际上用一个就够了???但是不好理解!! 所以我还是用了 ...
- 【10.7校内测试】【队列滑窗】【2-sat】【贪心+栈二分+线段树(noip模拟好题)】【生日祭!】
比较好想的一道题,直接用队列滑窗,因为扫一遍往队列里加东西时,改变的只有一个值,开桶储存好就行了! #include<bits/stdc++.h> using namespace std; ...
- 【10.6校内测试】【小模拟】【hash+线段树维护覆盖序列】
一开始看到题就果断跳到T2了!!没想到T2才是个大坑,浪费了两个小时QAQ!! 就是一道小模拟,它怎么说就怎么走就好了! 为什么要用这么多感叹号!!因为统计答案要边走边统计!!如果每个数据都扫一遍20 ...
随机推荐
- 已知可生成0~4的rand5(),实现生成0~6的rand7()
若已知生成0~6的rand7(),求生成0~4的rand5(),则一个方法就是不断生成0~7的数,直到这个数满足0~4就返回. int rand5(){ int res; do{ res = rand ...
- Serv-U 的升级及数据备份和迁移【转】
Serv-U 配置备份 在serv-u7.x及以上版本安装目录下,有一个文件Serv-U.Archive是serv-u的配置文件,有一个users文件夹是Serv-U的域和用户的信息,那么我们只需 ...
- PHP的数据库连接mysqli遍历示例
$mysqli = mysqli_init(); $mysqli->options(MYSQLI_OPT_CONNECT_TIMEOUT, 2);//设置超时时间,以秒为单位的连接超时时间 $m ...
- 二十、springboot之jpa开发@MappedSuperclass 注解说明
@MappedSuperclass使用条件: 当我们进行开发项目时,我们经常会用到实体映射到数据库表的操作,此时我们经常会发现在我们需要映射的几个实体类中,有几个共同的属性,例如编号ID,创建者,创建 ...
- URL的井号
2010年9月,twitter改版. 一个显著变化,就是URL加入了"#!"符号.比如,改版前的用户主页网址为 http://twitter.com/username 改版后,就变 ...
- 追MM与设计模式
1.FACTORY—追MM少不了请吃饭了,麦当劳的鸡翅和肯德基的鸡翅都是MM爱吃的东西,虽然口味有所不同,但不管你带MM去麦当劳或肯德基,只管向服务员说“来四个鸡翅”就行了.麦当劳和肯德基就是生产鸡翅 ...
- Elasticsearch 6.x 入门测试
首先听一下官方的话: https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html 我尝试了使用Java作为Cl ...
- PHP array_diff 计算数组的差集
array_diff (PHP 4 >= 4.0.1, PHP 5) array_diff — 计算数组的差集 说明 array array_diff ( array $array1 , arr ...
- MyBatis-Plus 3.0.7.1
1 .分页配置 <plugins> <plugin interceptor="com.baomidou.mybatisplus.plugins.PaginationInte ...
- Bootstrap--响应式导航条布局
<!DOCTYPE html> <html> <head> <meta name="viewport" content="wid ...