约瑟夫环与其变形问题

约瑟夫环问题描述:一圈共有N个人,开始报数,报到k的人自杀,然后重新开始报数,问最后自杀的人是谁?

思路:

  1.直接暴力模拟,没什么好说的,简单暴力。但是时间复杂度为O(n*m),太过浪费时间。

  2.动态规划,把问题重新描述一下:N个人(编号0~(N-1)),从0开始报数,报到(k-1)的自杀,剩下的人继续从0开始报数。求最后自杀者的编号。

我们用dp[i]来表示倒数第i轮自杀者的编号,那么最后一轮的自杀者在他说在轮的编号一定为0记作dp[1]=0,为了方便描述这个人记作p。那么在上一轮p的编号则为dp[2],在上一轮中p的前一位报号为(k-1),那么p的报号为k,

那么我们得出:dp[2]=(dp[1]+k)%k。如此下去我们便能的出p在最开始时的编号了。

状态转移方程式为:dp[i]=(dp[i-1]+k)%i,dp[1]=0,i(1->n);

 

约瑟夫环变形问题描述:一圈共有N个人,开始报数,第i轮报到i的人自杀,然后重新开始报数,问最后自杀的人是谁?

思路:

  和原本的约瑟夫环问题的唯一区别是:k值不在固定。同样的我们将最后一位自杀者叫做p,那么在前一轮(第x轮)中的自杀者所报的号为x-1,第x轮中p的报号为x,如此下去……

得出状态转移方程:dp[i]=(dp[i-1]+n-(i-1))%i; i(1->n)

代码:

void GSP(int n)
{
  jsp[1]=0;
  for(int i=2;i<=n;i++)
  {
    jsp[i]=(jsp[i-1]+(n-(i-1)))%i;
  }
}

 

转载于:https://www.cnblogs.com/alan-W/p/6709779.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值