T1 景区路线规划(期望dp/记忆化搜索)

一看题目发现肯定是概率期望题,再仔细想想这三天做的题,就知道是个期望dp。

考试思路(错):

因为聪聪与可可的10分打法根深蒂固,导致在考试时想到了用深搜(就不知道当时为什么没想到用那个题的正解思路.....)

深搜其实打的也挺对的,应该是能拿到55分(因为没用记忆化和数组记录更新状态),可是还犯了一个致命错误: 出度没有找对!!

看题:每玩完一个项目后,小y和妹子会等概率的随机选择一个可以从当前项目直达的且来得及玩的项目作为下一个项目。

意思就是每次的出度会可能跟刚开始初始化记录的出度不统一,于是应每次都找出度:

for(int i=r[st];i;i=e[i].next){
int v=e[i].to;
if(time+e[i].value+s[v].c>k) continue;
out++;
}

每次的概率都是之前的概率连乘出来的。

这样就可以写出来了:

 1 #include<bits/stdc++.h>
2 using namespace std;
3 const int NN=10005;
4 int n,m,k,tmp;
5 double hh1,hh2,H1[105][485],H2[105][485];
6 struct node{
7 int c,h1,h2;
8 };node s[105];
9 struct SNOW{
10 int to,next,value;
11 };SNOW e[NN]; int tot,r[NN];
12 inline void add(int x,int y,int z){
13 e[++tot]=(SNOW){y,r[x],z};
14 r[x]=tot;
15 }
16 inline double dfs1(int st,int time){
17 int out=0;
18 if(time>k) return 0.0;
19 if(H1[st][time]) return H1[st][time];
20 for(int i=r[st];i;i=e[i].next){
21 int v=e[i].to;
22 if(time+e[i].value+s[v].c>k) continue;
23 out++;
24 }
25 H1[st][time]=s[st].h1;
26 if(!out) return H1[st][time];
27 for(int i=r[st];i;i=e[i].next){
28 int v=e[i].to;
29 H1[st][time]+=dfs1(v,time+e[i].value+s[v].c)/out;
30 }
31 return H1[st][time];
32 }
33 inline double dfs2(int st,int time){
34 int out=0;
35 if(time>k) return 0.0;
36 if(H2[st][time]) return H2[st][time];
37 for(int i=r[st];i;i=e[i].next){
38 int v=e[i].to;
39 if(time+e[i].value+s[v].c>k) continue;
40 out++;
41 }
42 H2[st][time]=s[st].h2;
43 if(!out) return H2[st][time];
44 for(int i=r[st];i;i=e[i].next){
45 int v=e[i].to;
46 H2[st][time]+=dfs2(v,time+e[i].value+s[v].c)/out;
47 }
48 return H2[st][time];
49 }
50 namespace WSN{
51 inline int main(){
52 scanf("%d%d%d",&n,&m,&k);
53 for(int i=1;i<=n;i++)
54 scanf("%d%d%d",&s[i].c,&s[i].h1,&s[i].h2);
55 for(int i=1,x,y,z;i<=m;i++){
56 scanf("%d%d%d",&x,&y,&z);
57 add(x,y,z); add(y,x,z);
58 }
59 for(int i=1;i<=n;i++){
60 hh1+=dfs1(i,s[i].c)/n;
61 hh2+=dfs2(i,s[i].c)/n;
62 }
63 printf("%.5lf %.5lf",hh1,hh2);
64 return 0;
65 }
66 }
67 signed main(){return WSN::main();}

小结:

概率期望专题里这种题型不少见,感觉比聪聪与可可简单一些,还是要记住正解代码呀!!!


T2 [中山市选2009] 树(树规/高斯消元)

看到题目第一个肯定想到高斯消元,数据也比较合适,刚好也特别像专题里的开关问题,于是。。。我们讲讲正解的树规(俏展了)

状态数组:dp[n][2][2]表示第n个点操作(摁或不摁)后的状态(开或关);

状态转移也分成四种情况来搞,就差不多了。

最终状态:min(dp[1][1][1],dp[1][0][1]);

其他の注意 :

1.建边的数组开二倍(要不然MLE40);

2.要提前将dfs的点的状态值保存,要不然以后转移状态会串数。。。

3.不能将两种暂时不合法状态赋太大的值,否则转移会爆long long

 1 #include<bits/stdc++.h>
2 using namespace std;
3 const int NN=105;
4 int n,g[105][2][2];//i->节点x 0/1->不按/按x 0/1->不开/开x
5 struct SNOW{
6 int to,next;
7 };SNOW e[NN<<1]; int tot,r[NN<<1];
8 inline void add(int x,int y){
9 e[++tot]=(SNOW){y,r[x]};
10 r[x]=tot;
11 }
12 inline void snow(int x,int fa){
13 g[x][0][0]=0; g[x][1][1]=1; g[x][1][0]=n+1; g[x][0][1]=n+1;
14 for(int i=r[x];i;i=e[i].next){
15 int v=e[i].to;
16 if(v==fa) continue;
17 snow(v,x);
18 int g00=g[x][0][0],g01=g[x][0][1],g10=g[x][1][0],g11=g[x][1][1];//提前记录,否则状态转移时值会改变
19 g[x][0][0]=min(g01+g[v][1][1],g00+g[v][0][1]);
20 g[x][0][1]=min(g00+g[v][1][1],g01+g[v][0][1]);
21 g[x][1][0]=min(g11+g[v][1][0],g10+g[v][0][0]);
22 g[x][1][1]=min(g10+g[v][1][0],g11+g[v][0][0]);
23 }
24 }
25 namespace WSN{
26 inline int main(){
27 while(1){
28 memset(g,0,sizeof(g));
29 memset(r,0,sizeof(r));
30 tot=0;
31 scanf("%d",&n);
32 if(n==0) break;
33 for(int i=1,x,y;i<n;i++){
34 scanf("%d%d",&x,&y);
35 add(x,y); add(y,x);
36 }
37 snow(1,0);
38 printf("%d\n",min(g[1][1][1],g[1][0][1]));
39 }
40 return 0;
41 }
42 }
43 signed main(){return WSN::main();}

附上特殊的高斯消元打法

 1 #include<bits/stdc++.h>
2 using namespace std;
3 const int NN=105;
4 int n,g[NN][NN],wsn;
5 inline void Guass(){
6 int cnt=1;
7 for(int i=1;i<=n;i++){
8 int r=cnt;
9 for(int j=cnt+1;j<=n;j++) if(g[j][i]>g[r][i]) r=j;
10 if(!g[r][i]) continue;
11 if(r!=cnt) for(int j=i;j<=n+1;j++) swap(g[r][j],g[cnt][j]);
12 for(int j=1;j<=n;j++)
13 if(j!=cnt&&g[j][i])//将所有的系数都变历一遍,保证只剩下自由元
14 for(int k=i;k<=n+1;k++) g[j][k]^=g[cnt][k];
15 cnt++;
16 }
17 }
18 inline void dfs(int x,int line){//暴力搜索自由元
19 if(line>=wsn) return;
20 if(!x){ wsn=line; return;}
21 if(g[x][x]) dfs(x-1,line+g[x][n+1]);
22 else{
23 if(g[x][n+1]) return;
24 dfs(x-1,line);
25 for(int i=x;i>=1;i--) g[i][n+1]^=g[i][x];
26 dfs(x-1,line+1);
27 for(int i=x;i>=1;i--) g[i][n+1]^=g[i][x];
28 }
29 }
30 namespace WSN{
31 inline int main(){
32 while(1){
33 wsn=0x7fffffff;
34 memset(g,0,sizeof(g));
35 scanf("%d",&n);
36 if(n==0) break;
37 for(int i=1,x,y;i<n;i++){
38 scanf("%d%d",&x,&y);
39 g[x][y]=g[y][x]=1;
40 }
41 for(int i=1;i<=n;i++) g[i][i]=g[i][n+1]=1;
42 Guass();
43 dfs(n,0);
44 printf("%d\n",wsn);
45 }
46 return 0;
47 }
48 }
49 signed main(){return WSN::main();}

T3 奇怪的道路(状压dp)

考试时候真的没看出来是状压,那个1000000007看着太像排列组合里的东西了(还是太弱。。。)

状压思路有点像动物园;

得出状态转移数组: dp[i][j][u][t]表示第i个结点用了j条边情况下的前u位连边数状态(奇数0,偶数1),i的前t个点是第四维开的意义:

思路:

1.循环的时候避免开头几位找的数大,用一个min(i,k)来卡住范围;

2.如果不连: dp[i][j][u][t-1]+=dp[i][j][u][t];

3.如果连: dp[i][j+1][u^1^(1<<t)][t]+=dp[i][j][u][t];

4.2,3步将会把所有状态转移至第四维是0上;

5.如果开头是偶数,可以进行下一个节点的转移:dp[i+1][j][u<<1][min(i,k)]+=dp[i][j][u][0];

6.最终状态: dp[n][m][0][0];

7.初始状态: dp[1][0][0][0]=1;

 

 1 #include<bits/stdc++.h>
2 #define int long long
3 using namespace std;
4 const int momomo=1000000007;
5 int n,m,k,dp[35][35][1<<10][10];
6 namespace WSN{
7 inline int main(){
8 scanf("%lld%lld%lld",&n,&m,&k);
9 dp[1][0][0][0]=1;
10 for(int i=1;i<=n;i++)
11 for(int j=0;j<=m;j++)
12 for(int u=0;u<(1<<k+1);u++){
13 for(int t=min(i,k);t>=1;t--){
14 dp[i][j][u][t-1]=(dp[i][j][u][t-1]+dp[i][j][u][t])%momomo;
15 dp[i][j+1][u^1^(1<<t)][t]=(dp[i][j+1][u^1^(1<<t)][t]+dp[i][j][u][t])%momomo;
16 }
17 if(!((u>>k)&1)) dp[i+1][j][u<<1][min(i,k)]=(dp[i+1][j][u<<1][min(i,k)]+dp[i][j][u][0])%momomo;
18 }
19 printf("%lld\n",dp[n][m][0][0]);
20 return 0;
21 }
22 }
23 signed main(){return WSN::main();}

马の思

由于种种原因吧,这次考的比较崩,这三道题改下来感觉自己拿100+还是可行的毕竟第一题确实比较水

搭嘎(但是),毕竟自己只是拿了9分,就没什么可吹嘘的理由了,只能是暂且埋头苦干吧

5.24已是历史,抬头往前看才有阳光。。。。暂且鼓励自己一波

马の想

SNack:

你们快集训了吧,暑假要加油鸭!

小小马:

肯定会的,并且一直想你。。

梦开始的地方(Noip模拟3) 2021.5.24的更多相关文章

  1. Noip模拟70 2021.10.6

    T1 暴雨 放在第一道的神仙题,不同的做法,吊人有的都在用线段树维护$set$预处理 我是直接$dp$的,可能代码的复杂度比那种的稍微小一点 设$f[i][j][p][0/1]$表示考虑了前$i$列, ...

  2. Noip模拟63 2021.9.27(考场惊现无限之环)

    T1 电压机制 把题目转化为找那些边只被奇数环包含. 这样的话直接$dfs$生成一棵树,给每个点附上一个深度,根据其他的非树边都是返祖边 可以算出环内边的数量$dep[x]-dep[y]+1$,然后判 ...

  3. Noip模拟51 2021.9.12

    T1 茅山道术 考场上卡在了一个恶心的地方, 当时以为每次施法都会产生新的可以施法的区间,然后想都没细想, 认为不可做,甚至$dfs$也无法打,考后一问发现是自己想多了.. 新产生的区间对答案根本没有 ...

  4. Noip模拟84 2021.10.27

    以后估计都是用\(markdown\)来写了,可能风格会有变化 T1 宝藏 这两天老是会的题打不对,还是要细心... 考场上打的是维护\(set\)的做法,但是是最后才想出来的,没有维护对于是没有交. ...

  5. Noip模拟80 2021.10.18

    预计得分:5 实际得分:140?????????????? T1 邻面合并 我考场上没切掉的大水题....(证明我旁边的cty切掉了,并觉得很水) 然而贪心拿了六十,离谱,成功做到上一篇博客说的有勇气 ...

  6. Noip模拟79 2021.10.17(题目名字一样)

    T1 F 缩点缩成个$DAG$,然后根据每个点的度数计算期望值 1 #include<cstdio> 2 #include<cstring> 3 #include<vec ...

  7. Noip模拟76 2021.10.14

    T1 洛希极限 上来一道大数据结构或者单调队列优化$dp$ 真就没分析出来正解复杂度 正解复杂度$O(q+nm)$,但是据说我的复杂度是假的 考虑一个点转移最优情况是从它上面的一个反$L$形转移过来 ...

  8. Noip模拟69 2021.10.5

    考场拼命$yy$高精度结果没学好$for$循环痛失$50pts$,当场枯死 以后一定打对拍,要不考后会... T1 石子游戏 首先要知道典型的$NIM$博弈,就是说如果所有堆石子个数的异或和为$0$则 ...

  9. Noip模拟61 2021.9.25

    T1 交通 考场上想了一个$NPC$.应该吧,是要求出图里面的所有可行的不重复欧拉路 无数种做法都无法解出,时间也都耗在这个上面的,于是就考的挺惨的 以后要是觉得当前思路不可做,就试着换一换思路,千万 ...

  10. Noip模拟59 2021.9.22

    新机房首模拟变倒数 T1 柱状图 关于每一个点可以做出两条斜率分别为$1,-1$的直线, 然后题意转化为移动最少的步数使得所有点都在某一个点的两条直线上 二分出直线的高度,判断条件是尽量让这条直线上部 ...

随机推荐

  1. VUE003. 解决data中使用vue-i18n不更新视图问题(computed属性)

    案例 在国际化开发中,有一部分需要国际化的文字是由数据驱动的储存在data中,然而VUE的data存在很多无法实时更新视图的问题,比如v-for循环的标签,当数据层次过深,通过源数据数组的索引改变它的 ...

  2. python库--pymysql

    方法/类 返回值 参数 说明         .connect() ct 建立与mysql数据库的连接 host 数据库服务器所在的主机 user 用户名 password 密码 database 要 ...

  3. xshell与小键盘问题

    有些程序员的键盘是带有小数字键的,在使用xshell中文版时就可能出现一些小状况,本集就同大家分析一下使用数字键盘出现乱码的情况怎么办. 图1:使用数字小键盘出现乱码 问题描述: 在xshell上用v ...

  4. 机器学习——K-Means算法

    1 基础知识 相似度或距离 假设有 $m$ 个样本,每个样本由 $n$ 个属性的特征向量组成,样本合集 可以用矩阵 $X$ 表示 $X=[x_{ij}]_{mn}=\begin{bmatrix}x_{ ...

  5. 解决idea debugger Frames are not available

    现象:idea2017.3.7 sofaboot项目debugger报错 Frames are not available. 之前好用,不知道为啥突然不能debugger,run能正常运行代码.如下图 ...

  6. mybatis的mapper特殊字符转移以及动态SQL条件查询

    前言 我们知道在项目开发中之前使用数据库查询,都是基于jdbc,进行连接查询,然后是高级一点jdbcTemplate进行查询,但是我们发现还是不是很方便,有大量重复sql语句,与代码偶合,效率低下,于 ...

  7. Java基础系列(38)- 数组的使用

    数组的使用 For-Each循环 数组作方法入参 数组作返回值 For-Each循环 普通型 package array; import sun.security.util.Length; publi ...

  8. Docker系列(27)- 容器互联--link

    思考 思考一个场景,我们编写了一个微服务,database url=IP:,项目不重启,数据库ip换掉了,我们希望可以处理这个问题,可以使用名字来进行访问容器吗 实践 [root@localhost ...

  9. 传说中 VUE 的“语法糖”到底是啥?

    一.什么是语法糖? 语法糖也译为糖衣语法,是由英国计算机科学家彼得·约翰·兰达(Peter J. Landin)发明的一个术语.指的是计算机语言中添加的一种语法,在不影响功能的情况下,添加某种简单的语 ...

  10. django使用celery搭配redis配置定时任务

    已经安装环境: Python3.6 django==2.1.8(用2.2.2需要升级sqlite3) 项目名称:ceshiproject   APP名称:ceshi 第一步:centos7下首先安装r ...