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
原文地址:https://www.cnblogs.com/ZiningTang/p/4390647.html