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 };
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 };