【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 ...
随机推荐
- Add custom daemon on Linux System
Ubuntu add custom service(daemon) Task 需要在系统启动的时候自动启动一个服务(后台程序),在系统关闭的时候关闭服务. 比如在部署某个应用之前,需要将某个任务设置成 ...
- Linux压缩打包方法连载之三:bzip2, bzcat 命令
Linux压缩打包方法有多种,本文集中讲解了bzip2, bzcat 命令的使用.案例说明,例如# 与 gzip 同样的,都是在计算压缩比的参数,-9 最佳,-1 最快. AD: 我们遇见Linux压 ...
- PHP在引号前面添加反斜杠的原因及PHP去除反斜杠的办法
昨天用PHP做了个读写html文档的小程序,本地测试正常但是传到网站后发现,提交内容保存的时候会自动在双引号前面增加一个反斜杠“\”,而且每保存一次增加一个反斜杠,很是郁闷. 当然做这个只是为了参加电 ...
- SQLAlchemy-对象关系教程ORM-一对多(外键),一对一,多对多
一:一对多 表示一对多的关系时,在子表类中通过 foreign key (外键)引用父表类,然后,在父表类中通过 relationship() 方法来引用子表的类. 在一对多的关系中建立双向的关系,这 ...
- 日期时间设置 "2018-05-04T16:36:23.6341371+08:00" 格式
using System;using System.Collections.Generic;using System.Globalization;using System.Text; namespac ...
- c++中string类中的函数
C/C++ string库(string.h)提供了几个字符串查找函数,如下: memchr 在指定内存里定位给定字符 strchr 在指定字符串里定位给定字符 strcspn 返回在字符串str1里 ...
- H5新特性:video与audio的使用
HTML5 DOM 为 <audio> 和 <video> 元素提供了方法.属性和事件. 这些方法.属性和事件允许您使用 JavaScript 来操作 <audio> ...
- MySQL 连接本地数据库、远程数据库命令
一.MySQL 连接本地数据库,用户名为“root”,密码“123”(注意:“-p”和“123” 之间不能有空格) C:/>mysql -h localhost -u root -p123 二. ...
- 使用EasyWechat快速开发微信公众号支付
前期准备: 申请微信支付后, 会收到2个参数, 商户id,和商户key.注意,这2个参数,不要和微信的参数混淆.微信参数: appid, appkey, token支付参数: merchant_id( ...
- 第六届CCF软件能力认证
1.数位之和 问题描述 给定一个十进制整数n,输出n的各位数字之和. 输入格式 输入一个整数n. 输出格式 输出一个整数,表示答案. 样例输入 20151220 样例输出 13 样例说明 201512 ...