zoukankan      html  css  js  c++  java
  • HDU5860 (递推)

    Problem Death Sequence

    题目大意

      排成一行的约瑟夫问题。

      n个人排成一行,从第一个人开始,每个k个人报数,报到数的人被杀死,剩下的人重新排成一行再报数。

      一共q个询问,每次询问第qi个死的人是谁。

      n <= 3000000 , q <= 1000000 , k>=1 。

    解题分析

      显然每一轮游戏可以看做是一个子问题。

      假设编号为0~n-1,若某轮中某人的编号为i,如果i被k整除则被杀,否则在下轮中编号为i-i/k-1。

      dp[i]表示编号为i的人可以存活几轮,那么dp[i]=i % k ? dp[i-i/k-1] : 0 。

      再用一个数组s[i]记录一下前i轮一共死了多少人。

      这样就可以在O(n)时间内预处理出一个答案序列。

    参考程序

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<algorithm>
     7 #include<string>
     8 #include<iomanip>
     9 #include<vector>
    10 #include<set>
    11 #include<map>
    12 #include<queue>
    13 
    14 using namespace std;
    15 typedef long long LL;
    16 typedef unsigned long long ULL;
    17 
    18 #define rep(i,k,n) for(int i=(k);i<=(n);i++)
    19 #define rep0(i,n) for(int i=0;i<(n);i++)
    20 #define red(i,k,n) for(int i=(k);i>=(n);i--)
    21 #define sqr(x) ((x)*(x))
    22 #define clr(x,y) memset((x),(y),sizeof(x))
    23 #define pb push_back
    24 #define mod 1000000007
    25 
    26 const int maxn=3000300;
    27 int n,k,q,tot;
    28 int f[maxn],s[maxn],ans[maxn],a[maxn];
    29 
    30 void init()
    31 {
    32     int tmp=n;
    33     tot=0;
    34     s[0]=0;
    35     while(tmp)
    36     {
    37         tot++;
    38         s[tot]=s[tot-1]+(tmp-1)/k+1;
    39         tmp-=(tmp-1)/k+1;
    40     }
    41     f[0]=0;
    42     rep(i,0,n-1){
    43         f[i]= i % k ? f[i-i/k-1]+1 : 0 ;
    44         a[i]= i % k ? a[i-i/k-1] : i/k+1;
    45     }
    46     rep(i,0,n-1){
    47         int tmp=s[f[i]]+a[i];
    48         ans[tmp]=i;
    49     }
    50     //rep(i,1,n) printf("%d %d
    ",i,ans[i]+1 );
    51 }
    52 
    53 int main()
    54 {
    55     int t;
    56     scanf("%d",&t);
    57     while(t--)
    58     {
    59         scanf("%d%d%d",&n,&k,&q);
    60         init();
    61         while (q--){
    62             int x;
    63             scanf("%d",&x);
    64             printf("%d
    ",ans[x]+1);
    65         }
    66     }
    67     
    68     return 0;
    69 }
    View Code
  • 相关阅读:
    java线程池,工作窃取算法
    java线程池,阿里为什么不允许使用Executors?
    CMakeLists 的使用,大型工程使用cmake 的构件过程
    ieee文献免费下载办法
    欧式距离、标准化欧式距离、马氏距离、余弦距离
    sliding window:"Marginalization","Schur complement","First estimate jacobin"
    机器学习中的线性代数之矩阵求导
    opencv中滤波方法学习
    opencv关于Mat类中的Scalar()---颜色赋值
    C/C++预处理指令#define,#ifdef,#ifndef,#endif…
  • 原文地址:https://www.cnblogs.com/rpSebastian/p/5785911.html
Copyright © 2011-2022 走看看