HDU5860(约瑟夫环问题。超级牛B的动态规划思维题,DP嘛,推出递推式谁不会写)

来源:互联网 发布:网络电视怎样调出频道 编辑:程序博客网 时间:2024/06/05 08:22

题意:n个人站一排,从第一个人开始,每隔k个人死一个人,问第x次死的是哪个位置上的人。

题解:只需要知道一件事,如果这一轮第i个人死不了,下一轮他的位置是i-i/k-1。然后相当于又是一个子问题,就可以递推了。

#include<stdio.h>#include<stdlib.h>#include<string.h>#include<math.h>#include<iostream>#include<algorithm>#include<stack>#include<queue>#include<vector>#include<set>#include<map>#include<string>using namespace std;typedef long long ll;typedef pair<int,int>P;const int INF=0x3f3f3f3f;const ll INFF=0x3f3f3f3f3f3f3f3f;const ll mod=1e9+7;const double pi=acos(-1.0);const double eps=1e-9;int n,k,q;struct node1{    int x,y,pos;}node[3000010];bool cmp(node1 p1,node1 p2){    if(p1.x!=p2.x)        return p1.x<p2.x;    return p1.y<p2.y;}int main(){    int t;scanf("%d",&t);    while(t--)    {        scanf("%d%d%d",&n,&k,&q);        int l=1;        for(int i=0;i<n;i++)        {            if(i%k==0)            {                node[i].x=1;//第几轮死                node[i].y=l++;//第几个死                node[i].pos=i+1;//死的位置            }            else            {                node[i].x=node[i-i/k-1].x+1;                node[i].y=node[i-i/k-1].y;                node[i].pos=i+1;            }        }        sort(node,node+n,cmp);//先看轮数,再看每一轮数中的死亡顺序        while(q--)        {            int x;scanf("%d",&x);            printf("%d\n",node[x-1].pos);        }    }    return 0;}