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;
    }
    
  • 相关阅读:
    mybatis几种开发方式
    SpringData,JPA,MongoDB,Solr,Elasticsearch底层逻辑关系
    简论远程通信(RPC,Webservice,RMI,JMS的区别)
    spring/spring boot/spring mvc中用到的注解
    Centos常用命名
    Mybatis详解
    Java成长之路
    Hibernate 与Mybatis之比较
    Struts2 与SpringMVC之比较
    Maven 配置文件详解
  • 原文地址:https://www.cnblogs.com/qswx/p/9492568.html
Copyright © 2011-2022 走看看