zoukankan      html  css  js  c++  java
  • 慈善约瑟夫

    Description

    你一定听说过约瑟夫问题吧?即从n个人中找出惟一的幸存者。现在老约瑟夫将组织一个皆大欢喜的新游戏,假设n个人站成一圈,从第1个人开始交替的去掉游戏者,但只是暂去掉(例如,首先去掉2),直到最后剩下惟一的幸存者为止。

    幸存者选出后,所有比幸存者号码高的人每人将得到1TK(一种货币),永久性的离开。其余剩下的人将重复以上的过程,比幸存者号码高的每人将得到1Tk后离开。经过这样的过程后,一旦人数不再减少,则最后剩下的那些人将得到2TK。

    请你计算一下老约瑟夫一共要付出多少钱?

    Analysis

    题意表述不清,没有讲清Joseph游戏的关键数字,或许例如,首先去掉2是个提示,经尝试确实如此。

    很明显,这就是个多轮Joseph问题,处理每轮游戏后的奖金即可。那么,单轮Joseph怎么处理呢?对于i人的游戏来看,每次处决第2个人后,人数变为i-1,只是开始的下标改变了,所以再显然不过的状态转移:

    dp[i]=2+dp[i-1]
    

    当然,因为是个环所以要加上求余处理,为了方便将序号设为0~n-1,可以在之后处理时再加上1。得出n人游戏的幸运儿序号j后,每次将奖金加上n-j,再更新n和j,直到n=j则加上2·n。

    Code

    #include <bits/stdc++.h>
    
    int n,ans,dp[32768];
    
    int main(){
    	freopen("test.in","r",stdin);
    	freopen("test.out","w",stdout);
    	std::cin>>n;
    	dp[1]=0;
    	for(int i=2;i<=n;i++)
    		dp[i]=(dp[i-1]+2)%i;
    	for(int i=1;i<=n;i++)
    		dp[i]++;
    	int id=dp[n];
    	while(n>id){
    		ans+=n-id;
    		id=dp[n=id];
    	}
    	ans+=2*n;
    	std::cout<<ans<<std::endl;
    	return 0;
    }
    
  • 相关阅读:
    js返回到顶部
    css培训一
    css常用hack技巧
    css培训二
    css样式渲染规则
    html语义(一)
    css样式表管理
    html+css培训方案
    继承
    封装
  • 原文地址:https://www.cnblogs.com/qswx/p/9492568.html
Copyright © 2011-2022 走看看