1、在一个nxm的格子图上涂色,你每次可以选择一个未涂色的格子涂上你开始选定的那种颜色。同时为了美观,我们要求你涂色的格子不能相邻,也就是说,不能有公共边,现在问你,在采取最优策略的情况下,你最多能涂多少个格子?
2、作为一个马场的主人,你要安排你的n匹赛马和另一个马场的n匹马比赛。你已经知道了对方马场的出战表,即参加每一场的马的强壮程度。当然你也知道你自己的所有马的强壮程度。我们假定比赛的结果直接由马的强壮程度决定,即更壮的马获胜(若相同则双方均不算获胜),请你设计一个策略,使你能获得尽量多的场次的胜利。
3、你和你的朋友正在玩棋子跳格子的游戏,而棋盘是一个由n个格子组成的长条,你们两人轮流移动一颗棋子,每次可以选择让棋子跳1-3格,先将棋子移出棋盘的人获得胜利。我们知道你们两人都会采取最优策略,现在已知格子数目,并且初始时棋子在第一格由你操作。请你计算你是否能获胜。
4、A与B做游戏。 在一个n*m的矩阵中的出发点是(1,m),终点是(n,1),规则是只能向左移动一格,向下一格或向左下移动一格,先走到终点的为winner。 A先走。
给定两个整数n和m,请返回最后的获胜者的名字(A或B)。
②其他情况时,A先走一步后的情形对应其左边、上边和左上方的三种情况,不同的是,不管转移到这三种情况的哪一种,都变成了B先走。所以,A只要走到填0的那种情况,那么B必输。如果没有填0的情况,则无论A怎么走,A都会输。
③按照②中的策略,把整个表格填满。右下角的数字就代表A最终的输赢。
(1)动态规划的解法:
(2)从表中找到规律,即只有当n和m都是奇数的时候B才会赢。
解法:第一个格子要选相邻格子最少的,所以应该选四个角的格子。然后向格子四个角的方向延伸直到四个方向都抵达边界。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class
Paint {
public
:
int
getMost(
int
n,
int
m) {
if
(m%
2
==
0
)
return
(m/
2
)*n;
else
{
int
temp1 = (m+
1
)/
2
,temp2 = (n+
1
)/
2
;
return
temp1*temp2+(m-temp1)*(n-temp2);
}
}
};
解法: 先将两方的马的强壮程度由小到大排序。同时遍历我方的马和对方的马,若在对方的马中能找到强壮程度低于我方当前选中的马,则胜局数加1,且下次不再考虑对方的这匹马,依次进行,直到任意一方的马被遍历完。
class
HorseRace {
public
:
void
quickSort(vector<
int
> &arr,
int
start,
int
end) {
if
(start > end)
return
;
int
i = start,j = end;
int
base = arr[i];
while
(i < j) {
while
(i < j && arr[j] >= base) j--;
if
(i < j) {
arr[i] = arr[j];
i++;
}
while
(i < j && arr[i] <= base) i++;
if
(i < j) {
arr[j] = arr[i];
j--;
}
}
arr[i] = base;
quickSort(arr,start,i-
1
);
quickSort(arr,i+
1
,end);
return
;
}
int
winMost(vector<
int
> oppo, vector<
int
> horses,
int
n) {
int
res =
0
;
quickSort(oppo,
0
,n-
1
);
quickSort(horses,
0
,n-
1
);
for
(
int
i =
0
,j =
0
;i < n && j < n;i++) {
if
(horses[i] > oppo[j]) {
res++;
j++;
}
}
return
res;
}
};
解法:通过列举1、2、3、4格的情况发现,只要轮到我的时候还剩4格,我必输无疑,因为无论我选择走多少格对方都可以一次走出棋盘。更巧的是,无论我走多少格,对方都可以选择走一种格数来使这一回合凑齐4格。因此,
只要总格数是4的整数倍,我就必输无疑。而在其他任何种格数下,在走第一步的时候我都可以选择走一种格数使得剩下的格数为4的整数倍,这样对方就必输无疑。
class
Jump {
public
:
int
checkWin(
int
n) {
if
((n-
1
)%
4
==
0
)
return
0
;
else
return
1
;
}
};
解法:画图找规律,从一维推广到二维。用1表示A胜,0表示B胜。
①当矩阵只有一行或一列时,偶数格A胜,奇数格B胜。
0
|
1
|
0
|
1
|
0
|
1
|
1
|
|
|
|
|
|
0
|
|
|
|
|
|
1
|
|
|
|
|
|
0
|
|
|
|
|
|
0
|
1
|
0
|
1
|
0
|
1
|
1
|
1
|
|
|
|
|
0
|
|
|
|
|
|
1
|
|
|
|
|
|
0
|
|
|
|
|
|
0
|
1
|
0
|
1
|
0
|
1
|
1
|
1
|
1
|
1
|
1
|
1
|
0
|
1
|
0
|
1
|
0
|
1
|
1
|
1
|
1
|
1
|
1
|
1
|
0
|
1
|
0
|
1
|
0
|
1
|
class
Game {
public
:
char
getWinner(
int
n,
int
m) {
vector<vector<
int
> > dp(n,vector<
int
>(m));
for
(
int
i =
0
;i < n;i++) {
for
(
int
j =
0
;j < m;j++) {
if
(i ==
0
)
dp[i][j] = j%
2
==
0
?
0
:
1
;
else
{
if
(j ==
0
)
dp[i][j] =
1
^dp[i-
1
][j];
else
{
dp[i][j] =
1
^(dp[i-
1
][j]&dp[i-
1
][j-
1
]&dp[i][j-
1
]);
}
}
}
}
return
dp[n-
1
][m-
1
] ==
1
?
'A'
:
'B'
;
}
};
public
class
Game {
public
char
getWinner(
int
n,
int
m) {
if
((n %
2
==
1
) && (m %
2
==
1
))
return
'B'
;
return
'A'
;
}
}