TCO Algorithm round 2B

TCO Algorithm round 2B
涨了111 rating 真是耗rp啊.....

300pt

    有一个1到N(N<50)的排列,序列中的一些数被隐藏了(表示为0)。你每一次都可以选择数列中某个位置的一个数作为自己的得分,不论这个数是否被隐藏,你都会得到相应的分数。
    请问最少取多少个数能保证人品最坏的情况下至少拿到P(P<1,000,000)分。

思路分析

    因为RP总是很差,所以拿到被隐藏的数的时候是从最小开始拿的。如果每次都拿被隐藏的数的话,肯定是从小到大的一圈一圈的拿。
    如果拿没被隐藏的数的话,那么直接拿最大的就好了。
    于是算法和去年上海regional第一题就一样一样了.... 前面要么一圈一圈拿被隐藏的数,要么都拿最大的数。
    这个是贪心的。
    最后P会剩一个余数。
    暴力判断是拿最大的还是拿被隐藏的(2选1,交叉着来是不可能的...)。
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<vector>
 5 #include<cstring>
 6  using  namespace std;
 7  #define re(i,n) for(int i=0;i<n;i++)
 8  #define re1(i,n) for(int i=1;i<=n;i++)
 9  #define re2(i,n) for(int i=0;i<=n;i++)
10  #define re3(i,n) for(int i=1;i<n;i++)
11  #define clr(a,n) memset(a,n,sizeof(a))
12 template <typename T> inline T chkmin(T& a,T b){  return a > b ? a = b : a ; }
13 template <typename T> inline T chkmax(T& a,T b){  return a < b ? a = b : a ; }
14  int hash[100];
15  int cal( int P, int mx){
16      if(!mx)  return ~0u>>2;
17      return P/mx + (P%mx >0);
18 }
19  int cal( int P,vector< int> num){
20     sort(num.begin(),num.end());
21      int sum =0;
22     re(i,num.size()) {
23         sum+=num[i];
24          if(sum >= P)  return i+1;
25     }
26      return ~0u>>2;
27 }
28  class BlurredDartboard{
29      public :
30      int minThrows(vector < int> num,  int P){
31          int n = num.size(),mx = 0;
32         re(i,n){
33             hash[num[i]] = 1;
34             chkmax(mx,num[i]);
35         }
36         vector < int> temp;
37         re1(i,n)  if(!hash[i]) temp.push_back(i);
38          int m = temp.size(),suma = 0;
39         re(i,m) suma += temp[i];
40          if(!m) m = 1;
41          int sumb =  mx*m;
42          int sum= max(suma,sumb);
43          int ans = P/sum*m;
44         cout<<ans<<endl;
45         P %=sum;
46          if(P==0)  return ans;
47          int a = cal(P,mx);
48          int b = cal(P,temp);
49          return ans + min(a,b);
50     }
51 };
52 

550pt

    有N(N<50)本书,每本书都有一个价值w[i]。现在有M次操作,每次操作i(i=0 mod 2),小A可以从自己的书包拿出书向小B的书包里放最多move[i]本书。
    每次操作j(j=0 mod 1),小B可以从自己书包往小A书包里放最多move[j]本书。
    第一次操作,小A要从书堆中拿出move[0]本书装到B的书包中。
    最后,小A的书包中书的总价值为Wa,小B为Wb。小A想让Wb-Wa最大, 小B相让Wa-Wb最大.
    假设二个人都足够聪明.... 输出最后的Wa和Wb。
    如果有多种选择,那么输出Wa+Wb最大的那种可能。

思路分析

    没敲完... 残念啊... 我果然还是弱阿....
    显然除了第一步从书堆里放书意外,一旦书包中的书确定了,两人都是贪心的拿书。
    问题就是从书堆中拿哪些书...... DP就可以了吧....(ms有更简单的??)
    update: 下午闲着没事,就敲完了,可以去吃饭了(ms当时就是写完了也进不了前50.... 还是弱 阿....)
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<vector>
 6  using  namespace std;
 7  int hash[100];
 8  void work(vector< int> B,vector< int> num){
 9     vector< int> A;
10      for( int i=1; i< num.size();i++){
11          if(i&1){
12             sort(B.begin(),B.end());
13              int n = B.size();
14              int m = min(n,num[i]);
15              for( int j = n-1; j>= n-m; j--){
16                 A.push_back(B[j]);
17                 B.erase((vector< int>::iterator)&B[j]);
18             }
19         }
20          else {
21             sort(A.begin(),A.end());
22              int n = A.size();
23              int m = min(n,num[i]);
24              for( int j = n-1; j>= n-m; j--){
25                 B.push_back(A[j]);
26                 A.erase((vector< int>::iterator)&A[j]);
27             }
28         }
29     }
30      for( int i=0;i<A.size();i++) hash[A[i]] = -1;
31      for( int i=0;i<B.size();i++) hash[B[i]] = 1;
32 }
33  const  int inf = ~0u>>2;
34  int dp[100][100],P[100][100];
35  class HeavyBooks{
36      public : vector < int> findWeight(vector< int> book,vector < int> mv){
37         vector< int> temp;
38         sort(book.begin(),book.end());
39          int n =book.size();
40          int m = min(mv[0],n);
41          for( int i =0; i<m;i++) temp.push_back(i);
42         work(temp,mv);
43      //     for(int i=0;i<m;i++) cout<<hash[i]<<" "; cout<<endl;
44           for( int j=0;j<m;j++)
45              for( int i=j;i<n;i++)
46                  if(i == j){
47                     P[i][j] = i-1;
48                     dp[i][j] =(i ? dp[i-1][j-1]:0) + hash[j] * book[i];
49                 }
50                  else  if(j == 0){
51                     dp[i][0] = hash[0] * book[i];
52                     P[i][0] = -1;
53                 }
54                  else {
55                      int mx = -inf,s;
56                      for( int k = i-1; k>=j-1;k--)
57                          if(dp[k][j-1] > mx){
58                             s = k; mx = dp[k][j-1];
59                         }
60                     dp[i][j] = hash[j] * book[i] + mx;
61                     P[i][j] = s;
62                 }
63          int mx = -inf,s;
64          for( int i=n-1; i>=m-1;i--)
65              if(dp[i][m-1]>mx){
66                 s = i;
67                 mx = dp[i][m-1];
68             }
69          int A = 0, B = 0;
70          for( int i=m-1;i>=0;i--){
71              // cout<<s<<endl;
72               if(hash[i]>0) B += book[s];  else A += book[s];
73             s = P[s][i];
74         }
75         temp.clear();
76         temp.push_back(A);
77         temp.push_back(B);
78          return temp;
79     }
80 };
81 

你可能感兴趣的:(TCO Algorithm round 2B)