la_4727 Jump ( 经典模型变形 )

題意:

分析:

如果使用單純模擬的話,時間複雜度會比較大

這裡運用了DP的思想,如果知道1 到 n-1個人和k,最後退出的人的序號,那麼通過這個序號可以推算出1到n個人k的最後推出的人的序號

還不懂的建議自己去磨一下.

Code:

#include <cstdio>
#include <vector>
#include <cstring>
using namespace std;

const int MAXN = 500000;

int arr[10];

int location(int n, int k)
{
        int cnt = 0;
        vector<int> rst;
        memset(arr, 0, sizeof(arr));
        while( rst.size() < n ) {
                cnt = 0;
                for(int i = 1; ;) {
                        if( !arr[i] ) {
                                cnt += 1;
                                if( cnt == k ) {
                                        arr[i] = 1;
                                        rst.push_back(i);
                                        break;
                                }
                        }
                        i = i+1;
                        if( i > n ) {
                                i = 1;
                        }
                }
        }
        return rst[0];
}

int dp(int n, int k, int base)
{
        int cur, pre = location(base, k);
        for(int i = base+1; i <= n; i ++) {
                cur = (pre+k)%i;
                if( !cur ) {
                        cur = i;
                }
                pre = cur;
        }
        return cur;
}

int main(int argc, char **argv)
{
#ifndef ONLINE_JUDGE
        freopen("test.in", "r", stdin);
#endif
        int n, k, cas;
        scanf("%d", &cas);
        for(int z = 1; z <= cas; z ++) {
                scanf("%d %d", &n, &k);
                printf("%d %d %d\n", dp(n, k, 3), dp(n, k, 2), dp(n, k, 1));
        }
        return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值