srm555 div2

从金华回来,虽然创造了学校最好的排名,但是感觉下一场去成都仍然是有些没底,最近刷刷比赛玩玩……

A.简单题,枚举翻的行列,然后判断下最大的就行了。

class XorBoardDivTwo
{
        public:
        int theMax(vector<string> board)
        {
            int i,j,n,m,cnt=0,k,ans,tmp;
            n=board.size();
            m=board[0].size();
            for (i=0;i<n;i++)
            {
                for (j=0;j<m;j++)
                {
                    cnt+=board[i][j]-'0';
                }
            }
            ans=0;
            for (i=0;i<n;i++)
            {
                for (j=0;j<m;j++)
                {
                    tmp=cnt;
                    for (k=0;k<n;k++)
                    {
                        if (k==i) continue;
                        if (board[k][j]=='0') tmp++;
                        else tmp--;
                    }
                    for (k=0;k<m;k++)
                    {
                        if (k==j) continue;
                        if (board[i][k]=='0') tmp++;
                        else tmp--;
                    }
                    ans=max(ans,tmp);
                }
            }
            return ans;
        }
};

B.动态规划,dp[i]表示前面i个数最少可以分解为多少个5的次方数,然后就好转移了,注意下判断5的次方时可能会爆int。

class CuttingBitString
{
        public:

        int dp[1005];

        bool Check(string S,int l,int r)
        {
            long long i,ans=0;
            if (S[l]=='0') return false;
            for (i=l;i<=r;i++)
            {
                ans=ans*2+S[i]-'0';
            }
            if (ans==1) return true;
            if (ans<5) return false;
            while(ans!=1)
            {
                if (ans%5!=0) return false;
                ans/=5;
            }
            return true;
        }

        int getmin(string S)
        {
            int i,j,n;
            n=S.size();
            memset(dp,-1,sizeof(dp));
            dp[0]=0;
            for (i=0;i<n;i++)
            {
                if (dp[i]==-1) continue;
                for (j=i;j<n;j++)
                {
                    if (Check(S,i,j)==true)
                    {
                        if (dp[j+1]==-1) dp[j+1]=dp[i]+1;
                        else dp[j+1]=min(dp[j+1],dp[i]+1);
                    }
                }
            }
            return dp[n];
        }
};

C.动态规划

dp[i][j][k][l]表示前i个位置,有j个泥地,走到第i-1个位置的方法数的奇偶性为k,走到第i个位置的方法数的奇偶性为l的地形数量。

所以,如果第i+1个位置为泥地,那么dp[i+1][j+1][l][0]+=dp[i][j][k][l],因为不能走到泥地,所以奇偶性肯定是偶数。

如果不是泥地,那么dp[i+1][j][l][(k+l)%2]+=dp[i+1][j][k][l],就是类似斐波那契的递推。

注意取模。

class MuddyRoad2
{
        public:

        int dp[600][600][2][2];

        int theCount(int n, int muddyCount)
        {
            int i,j,k,l;
            dp[1][0][1][1]=1;
            dp[2][0][1][1]=1;
            dp[2][1][1][0]=1;
            for (i=2;i<n;i++)
            {
                for (j=0;j<=muddyCount;j++)
                {
                    for (k=0;k<2;k++)
                    {
                        for (l=0;l<2;l++)
                        {
                            dp[i+1][j][l][(k+l)%2]=(dp[i+1][j][l][(k+l)%2]+dp[i][j][k][l])%MOD;//no muddy
                            if (i+1<n) dp[i+1][j+1][l][0]=(dp[i+1][j+1][l][0]+dp[i][j][k][l])%MOD;//muddy
                        }
                    }
                }
            }
            return (dp[n][muddyCount][0][0]+dp[n][muddyCount][1][0])%MOD;
        }
};



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值