从金华回来,虽然创造了学校最好的排名,但是感觉下一场去成都仍然是有些没底,最近刷刷比赛玩玩……
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;
}
};