SRM 555 DIV 2
255pt:
题意:
给一个01矩阵,要求改变一行和一列是它的总和最大,求最大的总和,枚举行列,然后取抑或O(n^3)做即可;
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <stack> #include <set> #include <map> #include <string> #define CL(a,num) memset((a),(num),sizeof(a)) #define iabs(x) ((x) > 0 ? (x) : -(x)) #define Min(a,b) (a) > (b)? (b):(a) #define Max(a,b) (a) > (b)? (a):(b) #define ll long long #define inf 0x7f7f7f7f #define MOD 100000007 #define lc l,m,rt<<1 #define rc m + 1,r,rt<<1|1 #define pi acos(-1.0) #define test puts("<------------------->") #define maxn 100007 #define M 100007 #define N 107 using namespace std; //freopen("din.txt","r",stdin); class XorBoardDivTwo{ public: int theMax(vector <string> board){ int a[55][55]; int i,j; int sz = board.size(); int len = board[0].size(); int sum = 0; for (i = 0; i < sz; ++i){ for (j = 0; j < len; ++j){ a[i][j] = board[i][j] - '0'; sum += a[i][j]; } } int ans = -inf; int row,col; for (i = 0; i < sz; ++i){ for (j = 0; j < len; ++j){ int tmp = sum; for (col = 0; col < len; ++col){ a[i][col] ^= 1; if (a[i][col] == 0) tmp--; else tmp++; } for (row = 0; row < sz; ++row){ a[row][j] ^= 1; if (a[row][j] == 0) tmp--; else tmp++; } if (ans < tmp) ans = tmp; for (col = 0; col < len; ++col) a[i][col] ^= 1; for (row = 0; row < sz; ++row) a[row][j] ^= 1; } } return ans; } };
500pt;时间证明自己还是很弱,写完了测完样例刚想交呢,时间到了,无语,赛后提交过了。速度还是没有跟上。。
题意:
给定一个01串,将它分割成若干子串,子串的第一个数不能为0,而且每个子串要求保证是5的幂,求最小分割的快数;
思路:
DP: dp[i] = min(dp[i],dp[j] + 1) j是所有满足小于等于i且j + 1 与i这段子串满足5的幂。
首先预处理一下,求出每个点和他前边的点能够形成5的幂的点,并记录,然后就是O(n)走一遍dp;
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <stack> #include <set> #include <map> #include <string> #define CL(a,num) memset((a),(num),sizeof(a)) #define iabs(x) ((x) > 0 ? (x) : -(x)) #define Min(a,b) (a) > (b)? (b):(a) #define Max(a,b) (a) > (b)? (a):(b) #define ll long long #define inf 0x7f7f7f7f #define MOD 100000007 #define lc l,m,rt<<1 #define rc m + 1,r,rt<<1|1 #define pi acos(-1.0) #define test puts("<------------------->") #define maxn 100007 #define M 100007 #define N 107 using namespace std; //freopen("din.txt","r",stdin); class CuttingBitString{ public: int dp[55]; ll Pow(int a,int b){ ll sum = 1; for (int i = 1; i <= b; ++i){ sum *= a; } return sum; } //检查是否为5的幂 bool is5pow(int j,int i,int *a){ ll s = 0; for (int t = j,ct = 0; t >= i; --t,++ct){ s += (ll)a[t]*Pow(2,ct); } while (s%5 == 0){ s /= 5; } if (s != 1) return false; else return true; } int getmin(string S){ struct node{ int pre[55];// 记录当前点前边可以与他形成5的幂的点 int len; }b[55]; CL(b,0); int i,j; int a[55]; int sz = S.size(); for (i = 0; i < sz; ++i) a[i + 1] = S[i] - '0'; //记录过程 for (i = 1; i <= sz; ++i){ if (a[i] == 0) continue; for (j = i; j <= sz; ++j){ if (is5pow(j,i,a)){ b[j].pre[b[j].len++] = i - 1; } } } for (i = 1; i <= sz; ++i) { dp[i] = inf; } dp[0] = 0; for (i = 1; i <= sz; ++i){ // printf("I,B[i]len %d %d\n",i,b[i].len); for (j = 0; j < b[i].len; ++j){ int tmp = b[i].pre[j]; //printf(">>%d\n",tmp); dp[i] = min(dp[i],dp[tmp] + 1); } } /*for (i = 1; i <= sz; ++i) printf("%d ",dp[i]); test;*/ if (dp[sz] == inf) return -1; else return dp[sz]; } };