Joseph

    题目大意:给你2*k个人,前k个是好人,后k个是坏人,编号从1到2*k。每次从上一个死掉的人的下一个开始查m个人并将第m个人杀死。问最后剩下的全是好人的m是多少。

    注释:$1\le k \le 14$。

      想法:开始觉得自己想的有些简单,然后发现其实就是这码事。dp。

        dp状态:ans[i]表示第i个死的人

        转移方程:类似于Joseph问题,我们在递推时不断更改m的值,最终使得答案成立。

    最后,附上 丑陋的代码... ...

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int ans[30];
int Joseph[15];
// int Joseph[]={0,2,7,5,30,169,441,1872,7632,1740,93313,459901,1358657,2504881,1245064};//表
int main()
{
	int k;
	while(1)
	{
		scanf("%d",&k);
		if(!k) break;
		if(Joseph[k])
		{
			continue;
		}
		memset(ans,0,sizeof ans);
		int n=2*k;
		int m=k+1;
		for(int i=1;i<=k;i++)
		{
			ans[i]=(ans[i-1]+m-1)%(n-i+1);
			if(ans[i]<k)
			{
				i=0;
				m++;
			}
		}
		Joseph[k]=m;
		printf("%d\n",m);
	}
	return 0;
}

     小结:有趣qwq