• hdu 3089 约瑟夫环


    原来并不知道约瑟夫环还可以递推直接解orz

    约瑟夫问题的递推公式:

    设f[n]表示一共n个人,数到k出局,这样最后的winner (n个人从0开始标号,即0--n-1)

    f[n]=(f[n-1]+k)%n    (注意%n里这个n也是变量

    初值f[1]=0

    【公式的详细证明可以refer这里:http://blog.csdn.net/a725sasa/article/details/11664375 】

    不过本题n很大,O(n)仍然会爆

    注意到公式中的%n:如果f[n-1]+k小于n,那么就不用再mod了

    如果f[n-1]+若干个k还是很小,就可以一次多跳几步

    Reference:http://blog.csdn.net/gyarenas/article/details/9073045

     1 //f[1]=0    f[i]=(f[i-1]+m)%i
     2 //ty=(tx+m)%i
     3 #include<iostream>
     4 #include<cstdio>
     5 #include<cstring>
     6 using namespace std;
     7 #define LL long long
     8 LL n,k;
     9 
    10 LL solve(LL n,LL k)
    11 {
    12     LL i=2;
    13     LL tx=0;
    14     while(i<=n)
    15     {
    16         LL x=(i-1-tx)%(k-1)?(i-1-tx)/(k-1):(i-1-tx)/(k-1)-1;
    17         if(tx+k<i)
    18         {
    19             if(i+x>n)
    20             {
    21                 tx=tx+(n+1-i)*k;
    22                 return(tx);
    23             }
    24             tx=tx+x*k;
    25             i+=x;
    26         }
    27         else
    28         {
    29             tx=(tx+k)%i;
    30             i++;
    31         }
    32     }
    33     return(tx);
    34 }
    35 
    36 int main()
    37 {
    38     while(scanf("%I64d%I64d",&n,&k)!=EOF)
    39     {
    40         int i=2;
    41         LL tx=0;
    42         if(k==1)
    43         {
    44             tx=(n-1)%n;
    45         }
    46         else
    47             tx=solve(n,k);
    48         tx=(tx+1)%n;
    49         if(tx==0)   tx+=n;
    50         printf("%I64d
    ",tx);
    51     }
    52 }
    View Code
  • 相关阅读:
    mvc中HttpPost理解
    javascrip格式
    asp.net ToString()格式汇总
    Datatable根据多行排序
    sql server 判断是否存在数据库,表,列,视图
    IsPostBack是什么意思,如何运用?
    JS apply()的使用详解
    C++设计模式-Command命令模式
    C++ 继承和包含的区别?
    命令模式
  • 原文地址:https://www.cnblogs.com/pdev/p/4506757.html
Copyright © 2020-2023  润新知