有 n n n 个人玩复读游戏,如果复读的人不小于 p p p ,则倒数第 p p p 个复读的人会受到惩罚。
复读的规则如下:
会有好几轮行动,每一轮中,
n
n
n 个人依次执行以下动作:
若一轮中,没有任何人复读,则游戏结束。
第 i i i 个人如果其是第 j j j 个复读的人,则其可以获得 a i , j a_{i,j} ai,j 瓶冰红茶。但如果总复读人数不小于 p p p 个人,则倒数第 p p p 个人不会获得原有的冰红茶且倒扣 154 154 154 瓶冰红茶,换句话说,即获得 − 154 -154 −154 瓶冰红茶。
每个人都想最大限度地获得冰红茶,求最终每个人能获得多少冰红茶。
考虑如果所有
n
n
n 个人都参与复读。
在此情况下,
n
−
p
+
1
n-p+1
n−p+1 ~
n
n
n 这
p
p
p 个人中任意一个人作为第
n
−
p
+
1
n-p+1
n−p+1 个复读者参与复读,那么剩下的
p
−
1
p-1
p−1 个人一定不会受到惩罚,也一定会参与复读,导致第
n
−
p
+
1
n-p+1
n−p+1 个复读者受到惩罚,因此没有人会选择成为第
n
−
p
+
1
n-p+1
n−p+1 个复读者,所以
n
−
p
+
1
n-p+1
n−p+1 ~
n
n
n 一定不会参与复读游戏。
去掉这
p
p
p 个人后,设
n
′
=
n
−
p
n'=n-p
n′=n−p ,同样可以得到
n
′
−
p
+
1
n'-p+1
n′−p+1 ~
n
′
n'
n′ 也不会参与游戏,反复该过程,最终参与游戏的只会有
n
m
o
d
p
n\mod{p}
nmodp 个人参与复读游戏。
在此前提下,对于每个人而言,参与复读一定优于不参与复读,因此第一轮能参与复读的都会参与,总轮数只会有
1
1
1 轮,参与的恰好是最先的
n
m
o
d
p
n\mod{p}
nmodp 个人,第
i
i
i 个人的收益是
a
i
,
i
a_{i,i}
ai,i ,剩下的人无收益。
#include
using namespace std;
template<class T>inline void read(T&x){
char c,last=' ';
while(!isdigit(c=getchar()))last=c;
x=c^48;
while(isdigit(c=getchar()))x=(x<<3)+(x<<1)+(c^48);
if(last=='-')x=-x;
}
const int MAXN=1e3+5;
int n,p;
int a[MAXN][MAXN];
int main()
{
read(n),read(p);
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
read(a[i][j]);
}
}
for(int i=1;i<=n;++i){
if(i<=n%p)cout<<a[i][i]<<' ';
else cout<<0<<" \n"[i==n];
}
return 0;
}