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

    }

};

  

你可能感兴趣的:(div)