topcoder srm 548 div1 比赛小记

topcoder srm 548 div1 比赛小记
吐槽:
   无力吐槽了,450pt怎么那么难。。。

250pt
   题目意思是,有N(N<=50)个数,每个数的可变范围是[max(N-X,1),N+X]。让这个数列严格递增的最小X是多杀?
算法分析:
   二分枚举答案然后贪心判定。每个数都尽可能的小。
 1 #include<vector>
 2 #include<iostream>
 3  using  namespace std;
 4  class KingdomAndTrees{
 5      public :  int minLevel(vector < int> num){
 6          int n = num.size();
 7          int l = 0, r = 1000000000;
 8          while(l<r){
 9              int mid = l+r >>1;
10              int pre = 0, flag = 1;
11          //     cout<<l<<" "<<r<<" "<<mid<<endl;
12               for( int i=0;i<n;i++){
13                  if(num[i] + mid <= pre){ flag = 0;  break; }
14                 pre = max(pre+1, num[i] - mid);
15              //     if(mid == 5) cout<< pre<<" ";
16              }
17              if(flag) r = mid;  else l = mid+1;
18         }
19          return l;
20     }
21 };

450pt
   有两个N<50个面的骰子,每个面的数字是1-X的唯一某个数。第一个骰子有些面是0。现在两个骰子同时投掷,请你把第一个骰子某些为0的面写上一些唯一的1-X的数字,让第一个骰子的胜率尽可能接近0.5。

算法分析:
   等同于求,有一大堆数[1,X]。有N个空格,让你求在某些空格上写一些数,最后可以胜利的所有可能。
   背包模型,动规求解。DP[i][j][k],表示前i个骰子,填入前j个空格,是否可能赢k次。用0-1背包的写法,可以省一唯空间。

 1 #include<vector>
 2 #include<algorithm>
 3 #include<iostream>
 4  using  namespace std;
 5  bool dp[55][2555];
 6  class KingdomAndDice{
 7  public :  double newFairness(vector < int> fD, vector < int> sD,  int X){
 8      int now = 0, len = 0, n = sD.size();
 9      for( int i=0;i<n; i++){
10         len += fD[i] == 0;
11          for( int j=0; j<n; j++)
12             now += fD[i] > sD[j];
13     }
14     sort(sD.begin(), sD.end());
15      int mx = n*n;
16      for( int i=0;i<=len; i++) dp[i][now] = 1;
17      for( int i=0;i<n;i++){
18          int l = sD[i] + 1;
19          int r = i== n-1 ? X : sD[i+1] - 1;
20          int cnt = r - l + 1;
21          for( int j=0; j<n; j++)  if(fD[j] >=l && fD[j] <= r) cnt --;
22         cnt = min(cnt, len);
23          for( int j=0; j< cnt; j++)
24              for( int k = len-1;k >=0; k--)
25                  for( int p = 0; p <= mx; p++)
26                      if(dp[k][p] && p + i + 1 <= mx){
27                         dp[k+1][p + i + 1] = 1;
28                     }
29     }
30      int  m = abs(n*n ), ans = now;
31      for( int p = 0; p <=mx; p++){
32          for( int i=0; i<=len; i++)    {
33              if(dp[i][p] && abs(n*n-p*2) < m){
34                 ans = p; m = abs(n*n-p*2);
35             }
36         }
37     }
38      return 1.0*ans/mx;
39 }
40 };

你可能感兴趣的:(topcoder srm 548 div1 比赛小记)