zoukankan      html  css  js  c++  java
  • 约瑟夫问题例题小结

    类型1:约瑟夫问题原题:(http://acm.hdu.edu.cn/showproblem.php?pid=2925)

      大体就是一圈人,数到m的退出,询问最后留下来的人。

      这样的题是约瑟夫系列问题的基础,普通暴力做法O(n*m),不够优秀,可以通过数学方法优化至O(n),其所用的思路是将一个规模n的问题转移成规模n-1的问题。

        公式形式推导都很简单:f(i)表示规模i的约瑟夫问题最后留下人的编号,f(i)=(f(i-1)+m)%i

    类型2:规模变态版:(http://poj.org/problem?id=1781)

       类型1限制只数1,2,即每次去掉偶数项,易推导f(i)=(f(i-1)+2)%i

      然而数据时限卡O(n),通过《具体数学》上一种及其奇葩的推导,有一个O(log)解法,即f(i)=i循环右移(把二进制最高为的1放在最右面)

    类型3:类型1变式:(http://poj.org/problem?id=1012)

      2×n个人,通过约瑟夫方式间隔m杀人,使后n个坏人在前n个好人之前被杀的最小m。

      引入Joseph递推公式,设有n个人,(0~n-1),间隔m f(i) 表示当前子序列中第i轮要退出的那个人

        则 f(0)=0;

          f(i)=(f(i-1)+m-1)%(n-i+1);

      这个公式我真不知道是咋来的。。。

      反正假设我们知道这个公式,那么就可以从小大到枚举m,O(n)枚举。

    类型4:模型转变

      假设不再是圈,而是一个链,每次从没有死的第一个开始计数。

      这道题我确实是结合标程与打表找规律做出来的。

      打表每一轮死亡的人,设f(i,j)表示第i轮第j个死的人,我们可以将f(i,j)按照不同j值分类,这些都比较好想,

        这道题难点在于第a个人所表示的f(i,j)=a,则f(i-1,j)=a-a/k-1,人从0计数。

      上面做完就随便怎么都能做了。

    现在暂时总结这么多,总之约瑟夫问题足够神奇,也足够恶心。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define MAXN 1000000
    int f[MAXN];
    int main()
    {
    //        freopen("input.txt","r",stdin);
            int n,m;
            while (scanf("%d%d",&n,&m),n+m)
            {
                    f[1]=0;
                    int t,x;
                    for (int i=2;i<=n;i++)
                    {
                            f[i]=(f[i-1]+m%i)%i;
                    }
                    printf("%d %d %d
    ",n,m,f[n]+1);
            }
    }
    hdu 2925
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define MAXN 99000000
    const int ten[7]={1,10,100,1000,10000,100000,1000000};
    struct aaa
    {
            int val,id,ans;
    }al[10000];
    bool cmp_val(aaa a1,aaa a2)
    {
            return a1.val<a2.val;
    }
    bool cmp_id(aaa a1,aaa a2)
    {
            return a1.id<a2.id;
    }
    int main()
    {
        //    freopen("input.txt","r",stdin);
            char str[5];
            int n=0;
            while (scanf("%s",str),str[0]+str[1]+str[3]-'0'*3)
            {
                    int i,x;
                    x=((str[0]-'0')*10+str[1]-'0')*ten[str[3]-'0'];
                    al[n++].val=x;
                    al[n-1].id=n-1;
            }
            sort(al,al+n,cmp_val);
            int now=0;
            int x,y,z;
            int i;
            x=0;
            while (now<n && al[now].val==1)
                    al[now].ans=x+1;
            for (i=2;i<=MAXN;++i)
            {
                    x=(x+2)>=i?(x+2-i):(x+2);
                    while (now<n && al[now].val==i)
                            al[now++].ans=x+1;
            }
            sort(al,al+n,cmp_id);
            for (i=0;i<n;i++)
            {
                    printf("%d
    ",al[i].ans);
            }
    }
    poj 1781 O(n)
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define MAXN 99000000
    const int ten[7]={1,10,100,1000,10000,100000,1000000};
    
    int main()
    {
            freopen("input.txt","r",stdin);
            char str[5];
            int n=0;
            int x;
            while (scanf("%s",str),str[0]+str[1]+str[3]-'0'*3)
            {
                    x=((str[0]-'0')*10+str[1]-'0')*ten[str[3]-'0'];
                    for (int i=30;i>=0;i--)
                    {
                            if (x&(1<<i))
                            {
                                    printf("%d
    ",(((x^(1<<i))<<1)+1));
                                    break;
                            }
                    }
            }
    }
    poj 1781 O(log)
    by mhy12345(http://www.cnblogs.com/mhy12345/) 未经允许请勿转载

    本博客已停用,新博客地址:http://mhy12345.xyz

  • 相关阅读:
    Tomcat 配置 login 和 gas
    Mac系统终端命令行不执行命令 总出现command not found解决方法
    NodeJS入门---nodejs详细安装步骤
    Android UI 自动化-Android环境安装
    UI自动化-Chrome元素定位插件CreateXpath的安装及使用
    eclipse解决中文乱码
    pytest的allure的环境配置
    pytest基础简介及实践举例
    Appium 工作原理及 Desired Capabilities
    Appium_adb常用命令总结
  • 原文地址:https://www.cnblogs.com/mhy12345/p/4080192.html
Copyright © 2011-2022 走看看