Lightoj 1038 概率DP

来源:互联网 发布:淘宝活跃度是什么意思 编辑:程序博客网 时间:2024/06/05 20:45


题意:给一个数,用这个数的约数(包括自己)去除这个数,直到得数为1,求除的次数的期望。

#include <stdio.h>#include <string.h>#include <math.h>#include <iostream>#include<functional>#include <queue>#include <string>#include <algorithm>using namespace std;const int maxn = 100005;const int inf = 1<<30;const double eps = 1e-7;  int n;double dp[maxn];void init(){dp[1] = 0;for( int i = 2; i <= 100000; i ++ ){double sum = 0;int cnt = 0;for( int j = 1; j*j <= i; j ++ ){if( i%j == 0 ){sum += dp[j];cnt ++;if( j != i/j ){sum += dp[i/j];cnt ++;}}}dp[i] = ( sum + cnt )/( cnt - 1 );}}int main(){#ifndef ONLINE_JUDGE  freopen("data.txt","r",stdin);  #endif  init();int cas,c = 1;scanf("%d",&cas);while( cas -- ){scanf("%d",&n);printf("Case %d: %lf\n",c++,dp[n]);}return 0;}



#include <stdio.h>#include <string.h>#include <math.h>#include <iostream>#include<functional>#include <queue>#include <string>#include <algorithm>using namespace std;const int maxn = 100005;const int inf = 1<<30;const double eps = 1e-7;  int n;struct Edge{  int to, next;  }edge[maxn*20];  double dp[maxn];  int E,head[maxn];  void add_edge( int u, int to ){  edge[E].to = to;  edge[E].next = head[u];  head[u] = E++;  }  void init(){  E = 0;  memset( head, -1, sizeof(head) );  for ( int i = 0; i < maxn; i ++ ) dp[i] = 0.0;  for ( int x = 100000; x >= 2; x -- ){  for (int i = 2; i * i <= x; i ++ ){if (x % i == 0){  add_edge(x, i);  if( x / i != i )add_edge(x, x/i);  }  }}  }  double dfs( int u ){  if( dp[u] >= eps ) return dp[u];  if( u == 1 ) return 0.0;  double sum = 2;  int cnt = 2;  for( int i = head[u]; i != -1; i = edge[i].next ){  cnt++;  sum += dfs(edge[i].to) + 1;  }  return dp[u] = sum / (cnt-1);  }  int main(){#ifndef ONLINE_JUDGE  freopen("data.txt","r",stdin);  #endif  init();int cas,c = 1;scanf("%d",&cas);while( cas -- ){scanf("%d",&n);printf("Case %d: %f\n",c++,dfs(n));}return 0;}


0 0
原创粉丝点击