题目描述
众所周知,山羊和绵羊多年一来都在为他们的田地斗争。经过多年的争夺,山羊的领导人决定和绵羊的领导人见面,试图找到和平解决问题的方法。经过几个小时的讨论,他们决定在田地上都进行一场比赛,谁获胜谁就获得这块田地。
游戏内容是这样的:游戏总共有N只动物(可以使山羊或绵羊)他们围成一个圈(山羊和绵羊的确切顺序由他们的领导人决定),在第i个动物之后是第i+1个动物,第N个动物后是第1个动物。开始时,选择[1,K]之间的任何数字,但这个数字不能大于M。如果选择的这个数字是j,那么,下一个动物只能选择[j+1,j+K]之间的数字,同样这个数字不能大于M。换句话说,每个动物能够选择的数字,最小为1,最大为K,且这个数字不能比前面动物所选择的数字小,且这个数字不能大于M。当这个动物只能选择M或比M大的数时,它的团队(绵羊或者山羊)就会输。
如果山羊和绵羊都选择最佳的方式进行比赛,对于每一个i(1≤i≤N),如果从第i个动物开始,谁会赢得这场比赛。
输入格式
第一行输入三个数字N、M、K(1≤N,M,K≤5000)。
接下来输入N个只包含01的数字,0表示绵羊,1表示山羊。
输出格式
输出N个数字,表示从第i个动物开始比赛谁会获胜。如果绵羊获胜,则输出0,否则,输出1。
样例
样例输入1
2 9 2
0 1
样例输出1
0 1
样例输入2
6 499 5
1 0 0 1 1 0
样例输出2
0 1 1 1 1 0
样例输入3
10 100 10
0 0 0 1 1 1 1 0 1 1
样例输出3
1 1 1 1 1 1 1 1 1 1
数据范围与提示
对于样例1:如果从第1个动物开始(即绵羊),它可以选择数字范围是[1,2],它选择2,那么,山羊接下来只能选择3或者4.不管山羊选择3还是4,绵羊都能选择5。接下来,山羊能选择6或者7,同样的,无论山羊怎么选,绵羊都能选择8。接下来,山羊只能选择9,那么,它就会输掉比赛。
题目描述
众所周知,山羊和绵羊多年一来都在为他们的田地斗争。经过多年的争夺,山羊的领导人决定和绵羊的领导人见面,试图找到和平解决问题的方法。经过几个小时的讨论,他们决定在田地上都进行一场比赛,谁获胜谁就获得这块田地。
游戏内容是这样的:游戏总共有N只动物(可以使山羊或绵羊)他们围成一个圈(山羊和绵羊的确切顺序由他们的领导人决定),在第i个动物之后是第i+1个动物,第N个动物后是第1个动物。开始时,选择[1,K]之间的任何数字,但这个数字不能大于M。如果选择的这个数字是j,那么,下一个动物只能选择[j+1,j+K]之间的数字,同样这个数字不能大于M。换句话说,每个动物能够选择的数字,最小为1,最大为K,且这个数字不能比前面动物所选择的数字小,且这个数字不能大于M。当这个动物只能选择M或比M大的数时,它的团队(绵羊或者山羊)就会输。
如果山羊和绵羊都选择最佳的方式进行比赛,对于每一个i(1≤i≤N),如果从第i个动物开始,谁会赢得这场比赛。
输入格式
第一行输入三个数字N、M、K(1≤N,M,K≤5000)。
接下来输入N个只包含01的数字,0表示绵羊,1表示山羊。
输出格式
输出N个数字,表示从第i个动物开始比赛谁会获胜。如果绵羊获胜,则输出0,否则,输出1。
样例
样例输入1
2 9 2
0 1
样例输出1
0 1
样例输入2
6 499 5
1 0 0 1 1 0
样例输出2
0 1 1 1 1 0
样例输入3
10 100 10
0 0 0 1 1 1 1 0 1 1
样例输出3
1 1 1 1 1 1 1 1 1 1
数据范围与提示
对于样例1:如果从第1个动物开始(即绵羊),它可以选择数字范围是[1,2],它选择2,那么,山羊接下来只能选择3或者4.不管山羊选择3还是4,绵羊都能选择5。接下来,山羊能选择6或者7,同样的,无论山羊怎么选,绵羊都能选择8。接下来,山羊只能选择9,那么,它就会输掉比赛。
这道题是经典的博弈论,我们设DP[i][j]表示到第i只羊,它还有j个数可以说(它恰好也说第倒数第j个数),它的团队能否赢
我们这样想,如果它后面的羊和自己是一队的,那么如果后面的羊在说(以下皆省略倒数)j + 1到j + 1 + k这几个数中有一个是赢,那么当前的羊说第j个数,后面的羊必然去说能赢的那个数,因此DP[i][j] = 1(表示赢,0表示输)
如果后面的羊说j + 1到j + 1 + k这几个数中没有一个能赢,那么DP[i][j] = 0(必输无疑)
如果后面的羊跟自己不是一队的,那么后面的羊在说j + 1到j + 1 + k这几个数时,如果有一个是赢,那么自己必输DP[i][j] = 0
如果后面的羊说j + 1到j + 1 + k这几个数时,如果没有一个是赢,那么对方只有输,自己就可以赢DP[i][j] = 1
总结一下,我们把后面的羊说j + 1到j + 1 + k这几个数输赢情况加起来 记作SUM[i + 1][j] 羊的类别数组为A 如果是第N只羊
自然后面的羊是第1个 这个要单独判断
if(A[i] == A[i + 1])
if(SUM[i + 1][j - 1])因为这个羊说了这个数,下一个羊就只有j - 1个数可以说
DP[i][j] = 1;
else
DP[i][j] = 0;
else
if(SUM[i + 1][j - 1])
DP[i][j] = 0;
else
DP[i][j] = 1;
至于SUM的处理,可以像前缀和那样搞!
#include <cstdio>
#define reg register
int n, k, m, a[5005], dp[5005][5005], sum[5005][5005];
int main(){
scanf("%d%d%d", &n, &m, &k);
for(reg int i = 1; i <= n; i++){
scanf("%d", &a[i]);
}
for(reg int i = 1; i <= n; i++){
dp[i][0] = 0;
}
for(reg int i = 1; i < k; i++){
if(a[n] == a[1]){
if(sum[1][i - 1] > 0){
dp[n][i] = 1;
}
sum[n][i] = sum[n][i - 1] + dp[n][i];
}
else {
if(sum[1][i - 1] == 0){
dp[n][i] = 1;
}
sum[n][i] = sum[n][i - 1] + dp[n][i];
}
for(reg int j = 1; j < n; j++){
if(a[j] == a[j + 1]){
if(sum[j + 1][i - 1] > 0){
dp[j][i] = 1;
}
sum[j][i] = sum[j][i - 1] + dp[j][i];
}
else {
if(sum[j + 1][i - 1] == 0){
dp[j][i] = 1;
}
sum[j][i] = sum[j][i - 1] + dp[j][i];
}
}
}
for(reg int i = k; i < m; i++){
if(a[n] == a[1]){
if(sum[1][i - 1] > 0){
dp[n][i] = 1;
}
sum[n][i] = sum[n][i - 1] + dp[n][i] - dp[n][i - k];
}
else {
if(sum[1][i - 1] == 0){
dp[n][i] = 1;
}
sum[n][i] = sum[n][i - 1] + dp[n][i] - dp[n][i - k];
}
for(reg int j = 1; j < n; j++){
if(a[j] == a[j + 1]){
if(sum[j + 1][i - 1] > 0){
dp[j][i] = 1;
}
sum[j][i] = sum[j][i - 1] + dp[j][i] - dp[j][i - k];
}
else {
if(sum[j + 1][i - 1] == 0){
dp[j][i] = 1;
}
sum[j][i] = sum[j][i - 1] + dp[j][i] - dp[j][i - k];
}
}
}
for(reg int i = 1; i <= n; i++){
int winner = sum[i][m - 1] > 0 ? 1 : 0;
if(a[i] == 1){
printf("%d ", winner);
}
else {
printf("%d ", !winner);
}
}
return 0;
}
关注我
有惊喜
发红包
20元
要红包
请你找
ZYZ
小朋友