• SRM555-DIV1


    255point

    题意:给你一段0、1组成的字符串,数出最少的5的倍数有多少。

    做法:由题意范围,可知倍数的个数约有log(5, 2^50)(5为底) = 22个,因此预处理出所有满足5的倍数的字符串。

       dp[i]表示从左到右第i个数为止最少有多少个5的倍数的二进制串,枚举i->j中的每个点每次符合条件的,转移方程为:dp[i] = min(dp[j] + 1, dp[i]);

    复杂度:(n-1)n/2+22; (n为字符串长度)

    代码:

     1 class CuttingBitString{
     2 public:
     3     string *str;
     4     CuttingBitString() {
     5         str = new string[23];
     6         long long x = 5.1920929e15;
     7         int cnt = 0;
     8         stack<long long> q;
     9         for(long long i = 1; i <= x; i*=5) {
    10             long long b = i;
    11             while(b != 0) {
    12                 q.push(b%2);
    13                 b /= 2;
    14             }
    15             int xx = q.size();
    16             while(!q.empty()) {
    17                 str[cnt] += q.top()+'0';
    18                 q.pop();
    19             }
    20             cnt++;
    21         }
    22     }
    23     bool check(int l, int r, string s) {
    24         while(l < r && s[l] == '0') l++;
    25         string str2 = s.substr(l, r-l+1);
    26         for(int i = 22; i >= 0; i--) {
    27             if(str[i] == str2) return true;
    28         }
    29         return false;
    30     }
    31     int getmin(string S){
    32         int dp[60];
    33         int n = S.length(), ix;
    34 
    35         for(ix = 0; ix < n; ix ++) {
    36             if(S[ix] != '0') break;
    37         }if(ix == n) return -1;
    38 
    39         memset(dp, 0x7f, sizeof(dp));
    40         dp[ix] = 1;
    41         for(int i = ix+1; i < n; i++){
    42             if(check(ix, i, S)) dp[i] = 1;
    43             else {
    44                 for(int j = ix; j < i; j++) {
    45                     if(check(j+1, i, S)) {
    46                         dp[i] = min(dp[j] + 1, dp[i]);
    47                     }
    48                 }
    49             }
    50         }
    51         return dp[n-1];
    52     }
    53 
    54 };
    srm-555-1-233

    555point

    题意:H*W的矩阵初始矩阵内元素全为0,每次翻转为翻转一列/一行,翻转后该列/行全部元素原为0的变成1(反之则反),翻转Rcount次row,翻转Ccount次column,最后得到S个1.问实现这种翻转的方案数有多少。

    做法:可知对于一行的奇数次翻转有效,设a、b为有效翻转row、column次数, 则 H*a + W*b - 2*a*b = S。

      枚举每个合法的a、b,则对于每个a、b方案数为C(H, a) * C(W, b) * C(H+(Rcount-a)/2-1, H-1) * C(W+(Ccount-b)/2-1, W-1),所有的方案数之和便是解。

    复杂度:【预处理n^2/2】+ Rcount*Ccount

    代码:

     1 class XorBoard {
     2 public:
     3     int count(int H, int W, int Rcount, int Ccount, int S) {
     4         for ( int i = 0; i <= 4000; i ++ ) 
     5             for ( int j = 0; j <= min( i, 2000 ); j ++ ) c[i][j] = ( j == 0 ) ? 1 : ( c[i - 1][j] + c[i - 1][j - 1] ) % mol;
     6 
     7 
     8         long long cnt = 0;
     9         for(int i = 0; i <= Rcount; i++ ) {
    10             for(int j = 0; j <= Ccount; j++ ) {
    11                 if(i * W + j * H - 2*j*i == S && (Rcount - i) % 2 == 0 && (Ccount - j) % 2 == 0 && i <= H && j <= W) {
    12                     cnt = (cnt + c[H][i] * c[W][j] % mol * c[H+(Rcount-i)/2-1][(Rcount-i)/2] % mol * c[W+(Ccount-j)/2-1][(Ccount-j)/2] % mol) % mol;
    13                 }
    14             }
    15         }    
    16         return (int) cnt;
    17     }
    18 
    19 };
    srm-555-1-555
  • 相关阅读:
    【Static Program Analysis
    【Py-Github】根据条件筛选Github repo的例子
    【Static Program Analysis
    【Static Program Analysis
    【Static Program Analysis
    【Static Program Analysis
    【IEEE会议论文】格式规范问题
    搜索引擎(3)——查询理解——不可省词
    搜索引擎(2)—— 查询理解 —— 分词
    搜索引擎(1)—— 概述与功能架构
  • 原文地址:https://www.cnblogs.com/ZiningTang/p/4390647.html
Copyright © 2020-2023  润新知