算法学社
記錄難忘的征途
posts - 141,comments - 220,trackbacks - 0
吐槽:
   无力吐槽了,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 };

posted on 2012-07-04 12:05 西月弦 阅读(427) 评论(0)  编辑 收藏 引用

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理