SRM 583 DIV1

A

  裸最短路.

  

 1 class TravelOnMars {

 2 public:

 3     int minTimes(vector <int>, int, int);

 4 };

 5 vector<int> e[maxn];

 6 int n;

 7 

 8 int dist(int a,int b) {

 9     if (a>b) swap(a,b);

10     int res = min( b-a , a+n-b);

11     return res;

12 }

13 int d[maxn],inq[maxn];

14 queue<int> q;

15 int bfs(int s,int t) {

16     for (int i=0 ; i<n ; i++ ) d[i] = 1000;

17     d[s] = 0;

18     inq[s] = true;

19     q.push(s);

20     while (!q.empty()) {

21         int cur = q.front(); q.pop();

22         printf("d[%d]:%d\n",cur,d[cur]);

23         inq[cur] = false;

24         for (int i=0 ; i<(int)e[cur].size() ; i++ ) {

25             int v = e[cur][i];

26             if (d[v]>d[cur]+1) {

27                 d[v] = d[cur]+1;

28                 if (!inq[v]) {

29                     inq[v] = true;

30                     q.push(v);

31                 }

32             }

33         }

34     }

35     return d[t];

36 }

37 int TravelOnMars::minTimes(vector <int> range, int startCity, int endCity) {

38     n = range.size();

39     printf("n=%d\n",n);

40     for (int i=0 ; i<n ; i++ ) {

41         for (int j=0 ; j<n ; j++ ) if (dist(i,j)<=range[i]) {

42             e[i].push_back(j);

43         }

44     }

45     int ans = bfs(startCity,endCity);

46     return ans;

47 }
View Code

 

B

  f(u,s)表示以u为根子树的答案 , s=1表示有从u祖先下来的路径 , s=0表示没有.

  f(u,s) 可以通过一个dp得到 :

  dp[i][size]表示现在考虑第u的i个孩子,当前已经向下连了size条边时的最小代价 , 答案就是min(dp[ cntson ] [ size ] ),

  然后需要加一些强制转移.

  

  1 #include <vector>

  2 #include <list>

  3 #include <map>

  4 #include <set>

  5 #include <deque>

  6 #include <stack>

  7 #include <bitset>

  8 #include <algorithm>

  9 #include <functional>

 10 #include <numeric>

 11 #include <utility>

 12 #include <sstream>

 13 #include <iostream>

 14 #include <iomanip>

 15 #include <cstdio>

 16 #include <cmath>

 17 #include <cstdlib>

 18 #include <ctime>

 19 #include <cstring>

 20 using namespace std;

 21 #define maxn 55

 22 class TurnOnLamps {

 23 public:

 24     int minimize(vector <int>, string, string);

 25 };

 26 struct edge{

 27     int v,c;

 28 };

 29 

 30 vector<edge> e[maxn];

 31 bool debug;

 32 int var[maxn],n,dp[maxn][2],dp2[2][maxn][maxn];

 33 int getvar(int x) {

 34     if (x<0) return 0;

 35     int res =  x/2 + (x&1);

 36     if (debug) printf("var:%d = %d\n",x,res);

 37     return res;

 38 }

 39 int better(int a,int b) {

 40     if (a==-1) return b;

 41     if (b==-1) return a;

 42     return min(a,b);

 43 }

 44 int dfs(int u,int s,int fa) {

 45     if (dp[u][s]!=-1) return dp[u][s];

 46     vector<edge> son;

 47     for (int i=0 ; i<(int)e[u].size() ; i++ ) {

 48         int v = e[u][i].v;

 49         if (v==fa) continue;

 50         son.push_back(e[u][i]);

 51         dfs(v,0,u);

 52         dfs(v,1,u);

 53     }

 54     debug = (u==10);

 55     printf("u:%d s:%d debug=%d\n",u,s,debug);

 56     for (int i=0 ; i<(int)e[u].size() ; i++ ) if (e[u][i].v != fa) {

 57         printf("son:%d c:%d\n",e[u][i].v,e[u][i].c);

 58     }

 59 //    {{0, 1, 0, 2, 0, 1, 1, 2, 4, 6, 10, 10, 11, 10, 9, 9, 10, 15, 7}, "0111100111001010000", "0100001100101000111"}    

 60     int res = 0;

 61 //    for (int i=0 ; i<son.size() ; i++ ) printf("%d %d\n",son[i].v,son[i].c);

 62     if (son.size()) {

 63         if (son[0].c==0) {

 64             dp2[s][son[0].v][0] = dp[son[0].v][0];

 65             dp2[s][son[0].v][1] = dp[son[0].v][1] + getvar(1-s);

 66         } else if (son[0].c==1) {

 67             dp2[s][son[0].v][1] = dp[son[0].v][1] + getvar(1-s);

 68         } else if (son[0].c==2) {

 69             dp2[s][son[0].v][0] = dp[son[0].v][0];

 70         }

 71         for (int i=1 ; i<(int)son.size() ; i++ ) {

 72             int lastv = son[i-1].v;

 73             int v = son[i].v;

 74             int c = son[i].c;

 75             for (int j=0 ; j<=i ; j++ ) if (dp2[s][lastv][j] != -1) {

 76             if (u==10) printf("dp2[%d][%d][%d]=%d\n",s,lastv,j,dp2[s][lastv][j]);

 77         //        printf("dp2[%d][%d]=%d\n",lastv,j,dp2[lastv][j]);

 78                 if (c == 0) {

 79                     int tmp;

 80                     tmp = better(dp2[s][v][j] , dp2[s][lastv][j]+dp[v][0]);

 81             //        if (u==10) printf("update: dp2[%d][%d][%d] from %d to %d\n",s,v,j,dp2[s][v][j],tmp);

 82                     dp2[s][v][j] = tmp;

 83                     tmp = better(dp2[s][v][j+1] , dp2[s][lastv][j]-getvar(j-s)+dp[v][1]+getvar(j+1-s));

 84             //        if (u==10) printf("update: dp2[%d][%d][%d] from %d to %d\n",s,v,j+1,dp2[s][v][j+1],tmp);

 85                     dp2[s][v][j+1] = tmp;

 86                 } else if (c == 1) {

 87                     int tmp = better(dp2[s][v][j+1] , dp2[s][lastv][j]-getvar(j-s)+dp[v][1]+getvar(j+1-s));

 88             //        if (u==10) printf("update: dp2[%d][%d][%d] from %d to %d\n",s,v,j+1,dp2[s][v][j+1],tmp);

 89                     dp2[s][v][j+1] = tmp;

 90                 } else if (c == 2) {

 91                     int tmp = dp2[s][v][j] = better(dp2[s][v][j] , dp2[s][lastv][j]+dp[v][0]);

 92             //        if (u==10) printf("update: dp2[%d][%d][%d] from %d to %d\n",s,v,j,dp2[s][v][j],tmp);

 93                     dp2[s][v][j] = tmp;

 94                 }

 95             }

 96         }

 97         int smlcost = -1;

 98         int v = son[son.size()-1].v;

 99         for (int i=0 ; i<=(int)son.size() ; i++ )

100             if (dp2[s][v][i]!=-1) {

101                 smlcost = better(smlcost , dp2[s][v][i]);

102             }

103     //    if (smlcost != -1) res = smlcost;

104         res = smlcost;

105     }

106     printf("dp[%d][%d]=%d\n",u,s,res);

107     return dp[u][s] = res;

108 }

109 int TurnOnLamps::minimize(vector <int> roads, string init, string imp) {

110     n = roads.size()+1;

111     for (int i=0 ; i<n-1 ; i++ ) {

112         e[i+1].push_back((edge){roads[i],imp[i]=='1'?imp[i]-'0'+init[i]-'0':0});

113         e[roads[i]].push_back((edge){i+1,imp[i]=='1'?imp[i]-'0'+init[i]-'0':0});

114     }

115     memset(dp,-1,sizeof(dp));

116     memset(dp2,-1,sizeof(dp2));

117     int ans = dfs(0,0,-1);

118     return ans;

119 }
View Code


C

  概率题好费脑筋啊。。

  模拟样例算不对 , 后来发现是少算了转移到自己的情况 , 然后就不会做了: 考虑每次能转移到自己的情况会出现无数步 , 怎么计算期望就成了问题;

  题解在这个问题上处理地很巧妙 :

  (1) 从期望的公式出发,推导得到了一个简单的形式 : sum ( 第i步没有完成的概率 ) (0<=i <INF);

  (2) 可以用容斥来计算第i步没有完成的概率;

  (3) 将容斥的公式变形 , 得到一系列的收敛的无穷级数 , 于是解决了i有无穷多的问题;

  最后就得到了一个简单的统计模型: 对于给定的值x , 求有多少个元素个数为奇数的集合sum为x , 和有多少个个数为偶数的集合sum为x , 求他们的差,递推即可.

 1 #define maxn 2000

 2 class RandomPaintingOnABoard {

 3 public:

 4     double expectedSteps(vector <string>);

 5 };

 6 int cnt[maxn],sum[maxn],n,m,f[30][maxn],tot;

 7 double RandomPaintingOnABoard::expectedSteps(vector <string> prob) {

 8     n = prob.size();

 9     m = prob[0].size();

10     vector<string> tmp;

11     if (m>n) {

12         for (int i=0 ; i<m ; i++ ) {

13             string s = "";

14             for (int j=0 ; j<n ; j++ ) s += prob[j][i];

15             tmp.push_back(s);

16         }

17         prob = tmp;

18         swap (n,m);

19         for (int i=0 ; i<n ; i++ ) cout<<prob[i]<<endl;

20     }

21     double ans = 0;

22     printf("n:%d m:%d\n",n,m);

23     for (int i=0 ; i<n ; i++ ) for (int j=0 ; j<m ; j++ ) tot += prob[i][j]-'0';

24     for (int i=0 ; i<(1<<m) ; i++ ) {

25         

26     //    for (int j=0 ; j<n ; j++ ) sum[j] = 0;

27     //    for (int j=0 ; j<n ; j++ ) for (int k=0 ; k<=tot ; k++ ) f[j][k] = 0;

28         memset(sum,0,sizeof(sum));

29         memset(f,0,sizeof(f));

30         

31         for (int j=0 ; j<n ; j++ ) for (int k=0 ; k<m ; k++ ) if (((i>>k)&1)==0) {

32             sum[j] += prob[j][k]-'0';

33         }

34         f[0][0] = -1;

35         for (int j=0 ; j<m ; j++ ) if ((i>>j)&1) f[0][0] *= -1;

36         for (int j=0 ; j<n ; j++ ) for (int k=0 ; k<=tot ; k++ ) {

37             f[j+1][k] -= f[j][k];

38             if (k+sum[j]<=tot) f[j+1][k+sum[j]] += f[j][k];

39         }

40         for (int j=0 ; j<tot ; j++ ) cnt[j] += f[n][j];

41     }

42     for (int i=0 ; i<tot ; i++ ) {

43         ans += (double)cnt[i] * ((double)tot/(double)(tot-i));

44     }

45     return ans;

46 }

47 

48 

49 //Powered by [KawigiEdit] 2.0!
View Code

(http://apps.topcoder.com/wiki/display/tc/SRM+583)

你可能感兴趣的:(div)