BZOJ 1415聪聪和可可 期望dp
来源:互联网 发布:在线财神网淘宝店 编辑:程序博客网 时间:2024/05/17 01:54
1415: [Noi2005]聪聪和可可
Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 1750 Solved: 1026
[Submit][Status][Discuss]
Description
Input
数据的第1行为两个整数N和E,以空格分隔,分别表示森林中的景点数和连接相邻景点的路的条数。 第2行包含两个整数C和M,以空格分隔,分别表示初始时聪聪和可可所在的景点的编号。 接下来E行,每行两个整数,第i+2行的两个整数Ai和Bi表示景点Ai和景点Bi之间有一条路。 所有的路都是无向的,即:如果能从A走到B,就可以从B走到A。 输入保证任何两个景点之间不会有多于一条路直接相连,且聪聪和可可之间必有路直接或间接的相连。
Output
输出1个实数,四舍五入保留三位小数,表示平均多少个时间单位后聪聪会把可可吃掉。
Sample Input
【输入样例1】
4 3
1 4
1 2
2 3
3 4
【输入样例2】
9 9
9 3
1 2
2 3
3 4
4 5
3 6
4 6
4 7
7 8
8 9
Sample Output
【输出样例1】
1.500
【输出样例2】
2.167
HINT
对于所有的数据,1≤N,E≤1000。
对于50%的数据,1≤N≤50。
首先对于聪聪,他在s点时,可可在t点时,他下一步走的位置road[s][t]是确定的,所以我们可以利用广搜(SPFA)预处理出聪聪在点i,可可在点j时聪聪的下一步road[i][j]。//其实这一步的处理还是需要一点技巧
接下来就是转移的部分了。
设f[i][j]表示聪聪在i点,可可在j点时还期望多少步聪聪可以吃掉可可,不难得出f[i][j]可以从f[road[road[s][t]][t]][v]转移而来,v表示可可下一步所有可能的位置,包括当前的t,而每一个的概率为1/(q[t]+1)//q[t]表示t点的出度数
不要忘了每次f[i][j]+=1 毕竟又要走一步了。
一定要读题啊!读题啊!
1 聪聪先走可可后走
2.聪聪要是没吃到可可一次可以走两步 这就直接决定了附初始值:
road[road[s][t]][t]==t 或road[s][t]==t 时
f[s][t]=1.0.
当s==t 时,f[s][t]=0 //显然
代码:
#include<cstdio>#include<cstring>using namespace std;const int N = 1000 + 10;const int M = 2000 + 10;const int INF = 0x73f3f3f;int n,m;int s,t;struct node{ int pre,v;}edge[M];int num=0;int head[M];void addedge(int from,int to){ num++; edge[num].pre=head[from]; edge[num].v=to; head[from]=num;}int road[N][N];//road[i][j]表示聪聪在i时,可可在j时下一步应该移动到的点 int dis[N];int state[N*10];bool vis[N];#define ms(x,y) memset(x,y,sizeof(x))void SPFA(int s){//之前谁写的广搜求最短路啊 int h=0,tail=1; ms(dis,INF);ms(state,0);ms(vis,0); state[1]=s,dis[s]=0,vis[s]=true; do{ h++; int u=state[h];vis[s]=false; for(int i=head[u];i;i=edge[i].pre){ int v=edge[i].v; if(dis[v]>dis[u]+1){ dis[v]=dis[u]+1; if(!vis[v]){ vis[v]=true; tail++; state[tail]=v; } } } } while(h<tail);}double f[N][N];int q[N];double dfs(int s,int t){ if(f[s][t]) return f[s][t]; if(s==t) return 0;//在同一个地方 if(road[road[s][t]][t]==t||road[s][t]==t) return f[s][t]=1.0; double ans=dfs(road[road[s][t]][t],t); for(int i=head[t];i;i=edge[i].pre){ int v=edge[i].v; ans+=dfs(road[road[s][t]][t],v); } return f[s][t]=ans/(q[t]+1)+1;}int main(){ ms(q,0); scanf("%d%d",&n,&m); scanf("%d%d",&s,&t); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) f[i][j]=0.0; for(int i=1;i<=m;i++){ int u,v; scanf("%d%d",&u,&v); q[u]++,q[v]++; addedge(u,v); addedge(v,u); } for(int i=1;i<=n;i++){ SPFA(i); for(int j=1;j<=n;j++){ int mmax=INF; for(int k=head[j];k;k=edge[k].pre){ int v=edge[k].v; if(dis[v]<mmax||dis[v]==mmax&&v<road[j][i]){ mmax=dis[v]; road[j][i]=v; } } } }//终于找出聪聪怎么走了 //for(int i=1;i<=n;i++) // printf("%d ",road[4][i]);//连边完美 printf("%0.3lf",dfs(s,t)); return 0;}
- BZOJ 1415: [Noi2005]聪聪和可可 期望dp
- BZOJ 1415聪聪和可可 期望dp
- bzoj 1415 聪聪和可可 (期望dp)
- bzoj 1415 聪聪和可可 【期望】
- 【BZOJ】【P1415】【Noi2005】【聪聪和可可】【题解】【期望DP】
- NOI2005 BZOJ 1415聪聪和可可(期望+Floyd)
- [BZOJ 1415][Noi2005]聪聪和可可:期望
- BZOJ 1415 NOI2005 聪聪和可可 期望DP+记忆化搜索 BZOJ200题达成&&NOI2005全AC达成
- bzoj 1415 聪聪和可可(概率DP)
- BZOJ 1415: [Noi2005]聪聪和可可|概率dp
- BZOJ 1415 [Noi2005]聪聪和可可【概率dp】
- bzoj 1415 [Noi2005]聪聪和可可 概率dp
- 【NOI2005T4】聪聪和可可-期望DP+记忆化搜索
- 聪聪和可可(记忆化dp+数学期望)
- BZOJ 1415|NOI 2005|聪聪和可可|概率期望|动态规划
- bzoj 1415: [Noi2005]聪聪和可可 (概率与期望)
- 【BZOJ 1415】 [Noi2005]聪聪和可可
- BZOJ 1415: [Noi2005]聪聪和可可
- 神奇的 conic-gradient 圆锥渐变
- C语言二维数组行地址与列地址
- NIO
- websocket
- Hadoop 2.4.1伪分布式搭建
- BZOJ 1415聪聪和可可 期望dp
- c++小根堆数组实现
- Python获取目录下的全部文件名,并写入文件中
- hadoop2.4.1集群搭建
- 两个Transformed-前缀的mathematica函数
- SpringMVC 原理详解
- 安装android studio遇到的问题
- 【RMQ】poj 3264 Balanced Lineup
- 获取sd卡某路径下的图片,并展示出来